更改对象的原型会发生什么?

时间:2014-12-29 08:07:54

标签: javascript prototype

当我们这样做时会发生什么:

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对象共享它们)

2 个答案:

答案 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的原因是因为我们引用了原型。当你改变原型时会发生一些不同的事情。基于上面的简单示例,您可能会猜到它是什么。

建议在创建实例后重新分配原型,因为这可能会对优化产生负面影响,并使任何试图维护代码的人感到困惑。

有关原型和继承模式的更多信息,请访问:

https://stackoverflow.com/a/16063711/1641941