Reputation: 682
What happens when we do:
Cat.prototype = new Mammal();
My guess is that, besides changing __proto__
, nothing really happens, and Cat.prototype
is not changed. Or if it is, then properties are copied to it, and it's not replaced by the new object we just created.
Any ideas?
this is it: the mistake was using myCat.prototype which is undefined... when you check Cat.prototype you can see that it is replaced too
var myCat = new Cat();
alert(myCat.__proto__ instanceof Mammal); // true
alert(myCat.__proto__ instanceof Cat); // false
alert(Cat.prototype instanceof Mammal); // true
alert(Cat.prototype instanceof Cat); // false
we don't want to call new here, you are right, cause that will cause object members of Mammal instance to be prototype members of Cat. (the constructor of Mammal is called and create its members as the prototype members where they are shared by all Cat objects)
Upvotes: 0
Views: 662
Reputation: 39270
Object instances do not have a member called prototype
unless they are functions (var f = new Function() is a Function instance). It is explained in the link I posted in the comment and this answer.
Instanceof can depend on when you replace the prototype and the __proto__
for instances created by the same constructor function can be different.
var pr = {
speak:function(){
console.log('I am the original');
}
};
var Animal = function(){};
Animal.prototype = pr;
var original = new Animal();
//Now we de reference the prototype of Animal
// this will cause instances already created to
// still use original but new instances will use the copy
Animal.prototype = {
speak:function(){
console.log('I am changed');
}
};
var changed = new Animal();
console.log(original.speak());//=I am the original
console.log(changed.speak());//=I am changed
A much simpler example (without using prototype) shows what is going on here:
var org = {name:'org'};
var copy = org;//org and copy point to the same object
console.log(copy === org);//true
copy.name='first change';//mutating copy will affect org
//because they point to the same object
console.log(org.name);//=first change
copy = {name:'de reference'};//re assigning copy will de reference copy
//copy no longer points to the same object as org
console.log(copy === org);//=false
console.log(org.name);//=first change
So when prototype is involved something similar happens.
The Animal instance stored in original
uses pr as it's prototype but the Animal instance changed
does not, the reason why original still uses pr is because we de referenced the prototype. When you mutate the prototype something different happens. Based on the simpler example above you may guess what that is.
It is not advisable to re assign the prototype after creating instances as this could negatively affect optimization and confuse anyone trying to maintain your code.
More info on prototype and inheritance patterns can be found here:
https://stackoverflow.com/a/16063711/1641941
Upvotes: 0
Reputation: 224913
my guess is that besides changing proto nothing really happens and Cat.prototype is not changed or if it is then properties are copied to it and its not replaced by the new object we just created
No, it is definitely completely replaced.
function Mammal() {
}
function Cat() {
}
Cat.prototype.meow = function () {
console.log('Meow!');
};
Cat.prototype = new Mammal();
new Cat().meow(); // “TypeError: undefined is not a function” or equivalent
(Cat.prototype = Object.create(Mammal);
would be the better way to inherit Mammal
, by the way.)
Upvotes: 4