Consider the following code.
function a() {}
function b() {}
function c() {}
b.prototype = new a();
c.prototype = new b();
console.log((new a()).constructo
constructor
is a regular, non-enumerable property of the default value of the prototype
property of function objects. Thus, assigning to prototype
will lose the property.
instanceof
will still work as it does not use constructor
, but rather scans the prototype chain of the object for the (current) value of the function's prototype
property, ie foo instanceof Foo
is equivalent to
var proto = Object.getPrototypeOf(foo);
for(; proto !== null; proto = Object.getPrototypeOf(proto)) {
if(proto === Foo.prototype)
return true;
}
return false;
In ECMAScript3, there's no way to set a constructor
property which behaves identically to the built-in one as user-defined properties are always enumerable (ie visible to for..in
).
This changed with ECMAScript5. However, even if you set constructor
manually, your code still has issues: In particular, it is a bad idea to set prototype
to an instance of the parent-'class' - the parent constructor should not be called when the child-'class' is defined, but rather when child-instances are created.
Here's some ECMAScript5 example code for how it should be done:
function Pet(name) {
this.name = name;
}
Pet.prototype.feed = function(food) {
return this.name + ' ate ' + food + '.';
};
function Cat(name) {
Pet.call(this, name);
}
Cat.prototype = Object.create(Pet.prototype, {
constructor : {
value : Cat,
writable : true,
enumerable : false,
configurable : true
}
});
Cat.prototype.caress = function() {
return this.name + ' purrs.';
};
If you're stuck with ECMAScript3, you'll need to use a custom clone() function instead of Object.create()
and won't be able to make constructor
non-enumerable:
Cat.prototype = clone(Pet.prototype);
Cat.prototype.constructor = Cat;