Reputation: 2848
I try to create a dynamic prototype like jQuery and able to function chain, but I got error without use new and inside of function, return this
object correct?
(function() {
var peopleDynamicProto = function(name, age, state) {
this.name = name;
this.age = age;
this.state = state;
if (typeof this.printPerson !== 'function') {
peopleDynamicProto.prototype.printPerson = function() {
console.log(this.name + ',' + this.age + ',' + this.state);
return this;
};
}
if (!this.hasOwnProperty('gender')) {
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
//var person1 = new peopleDynamicProto('john', 23,'CA');
//person1.printPerson();
peopleDynamicProto('john', 23, 'CA').printPerson(); //got error
Anyone know where is the problem?
Upvotes: 1
Views: 397
Reputation: 109
you cant create prototype inside contructor. see this explanation defining-prototype-methods-inside-the-constructor
use this keyword instead of prototype:
(function(){
var peopleDynamicProto = function(name, age, state){
this.name = name;
this.age = age;
this.state = state;
this.printPerson = function(){
console.log( this.name + ',' + this.age + ',' + this.state );
return this;
}
if( !this.hasOwnProperty('gender') ){
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
peopleDynamicProto('john', 23,'CA').printPerson();
or use prototype outside constructor(this is better since function object not recreated each time object created)
(function(){
var peopleDynamicProto = function(name, age, state){
this.name = name;
this.age = age;
this.state = state;
if( !this.hasOwnProperty('gender') ){
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
if( typeof this.printPerson !== 'function' ){
peopleDynamicProto.prototype.printPerson = function(){
console.log( this.name + ',' + this.age + ',' + this.state );
return this;
};
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
Upvotes: 1
Reputation: 42352
I guess you missed the new
operator- see this for reference
The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function.
See demo below:
(function() {
var peopleDynamicProto = function(name, age, state) {
this.name = name;
this.age = age;
this.state = state;
if (typeof this.printPerson !== 'function') {
peopleDynamicProto.prototype.printPerson = function() {
console.log(this.name + ',' + this.age + ',' + this.state);
return this;
};
}
if (!this.hasOwnProperty('gender')) {
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
var person1 = new peopleDynamicProto('john', 23,'CA');
person1.printPerson();
new peopleDynamicProto('john', 23, 'CA').printPerson(); //got error
Upvotes: 1
Reputation: 2950
You have to use "new" if you want to create a new object based off a prototype.
I am not sure what you are trying to do exactly, and why you are trying to create the prototype dynamically. I'm not going to say 100% sure, but I don't think jQuery does that (plus it looks like a very bad practice).
If you're trying to do something like jQuery, where your class is chainable and can be chained as (new peopleDynamicProto(...)).print()
or peopleDynamicProto(...).print()
, then you can do something like this:
function peopleDynamicProto(name) {
if (this instanceof peopleDynamicProto) {
/* initialize attributes here */
this.name = name;
} else {
return new peopleDynamicProto(name);
}
}
peopleDynamicProto.prototype.printPerson = function() {
console.log( this.name );
return this;
}
Now you should be able call it in both ways:
peopleDynamicProto('john').printPerson();
(new peopleDynamicProto('john')).printPerson();
If you don't care about supporting both ways, then you can just return an object, e.g.:
function peopleDynamicProto(name) {
return {
name: name,
printPerson = function() {
console.log( this.name );
return this;
}
};
}
peopleDynamicProto('John').printPerson();
(There are other ways of doing that)
Upvotes: 3
Reputation: 1550
I think the reason why you are getting such an error is because what you are returning here is a function not an object but you are trying to access a property of an object.
For eg, If you write as:
**
var myFun = function(){
this.message = "TEST";
}
**
you cannot access myFUN.message because here myFun is a function not an object of this function constructor.
To access its property, you need to do something like (new myFun()).message;
Similarly in you case what you return is "peopleDynamicProto" which is a function only, not an object of this function constructor.
To access method printPerson (which is a member), you need to create an instance of peopleDynamicProto and access its member
Upvotes: 2