当我们这样做时会发生什么:
Cat.prototype = new Mammal();
我的猜测是,除了更改__proto__
之外,没有真正发生任何事情,Cat.prototype
也没有改变。或者如果是,则将属性复制到它,并且它不会被我们刚刚创建的新对象替换。
有什么想法吗?
就是这样: 错误是使用未定义的myCat.prototype ... 当您检查Cat.prototype时,您可以看到它也被替换
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
我们不想在这里调用new,你是对的,因为这会导致Mammal实例的对象成员成为Cat的原型成员。 (调用Mammal的构造函数并将其成员创建为原型成员,所有Cat对象共享它们)
答案 0 :(得分:4)
我的猜测是,除了改变proto之外没有任何事情发生,Cat.prototype没有改变,或者如果是,那么属性被复制到它并且它不会被我们刚创建的新对象替换
不,它绝对完全被替换。
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);
是继承Mammal
的更好方式。)
答案 1 :(得分:0)
对象实例没有名为prototype
的成员,除非它们是函数(var f = new Function()是一个Function实例)。我在评论和这个答案中发布的链接中对此进行了解释。
Instanceof可以取决于您何时替换原型,而__proto__
对于由相同构造函数创建的实例可能会有所不同。
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
一个更简单的例子(不使用原型)显示了这里发生了什么:
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
因此,当涉及原型时会发生类似的事情。
存储在original
中的Animal实例使用pr作为它的原型,但Animal实例changed
没有,原始仍然使用pr的原因是因为我们引用了原型。当你改变原型时会发生一些不同的事情。基于上面的简单示例,您可能会猜到它是什么。
建议在创建实例后重新分配原型,因为这可能会对优化产生负面影响,并使任何试图维护代码的人感到困惑。
有关原型和继承模式的更多信息,请访问: