为什么替换构造函数的原型没有反映在对象中?

时间:2015-02-22 05:59:53

标签: javascript

如果我只使用obj.prototype.property = val,一切都会好的,代码如

function animal() {}
var frog = new animal();
animal.prototype.color = 'Green';
console.log(frog.color);
// 'Green'

但如果我在新关键字后使用obj.prototype = {key:val},它会给我一个undefined,代码如

function animal() {}
var frog = new animal();
animal.prototype = {
    color: 'Green'
};
console.log(frog.color);
// 'undefined' -- why?

如果我在新关键字之前更改了原型的顺序,那就没关系了,这很奇怪,为什么?因为我们知道对象的原型允许我们向该对象的所有实例添加属性(甚至是现有的实例),对吗?

代码

function animal() {}
animal.prototype = {
    color: 'Green'
};
var frog = new animal();
console.log(frog.color);
// 'Green'

2 个答案:

答案 0 :(得分:1)

当您使用new关键字创建新对象时,新创建的对象的内部[[Property]]对象将被设置为构造函数的原型对象。

function animal() {}
var frog = new animal();

console.log(Object.getPrototypeOf(frog) === animal.prototype);
# true

animal.prototype = {
    color: 'Green'
};

console.log(Object.getPrototypeOf(frog) === animal.prototype);
# false

console.log(frog.color);

在第一个console.log中,它会打印true,因为new已将animal的{​​{1}}对象设为{{1}内部prototype对象的内部frog对象。但是,当您将一些其他对象分配给[[Prototype]] animal时,prototype的内部frog对象仍然引用旧对象,没有[[Prototype]]财产。这就是打印color的原因。

当您更改订单时,遇到undefined语句时,它会获取new' animal对象(您指定的新对象),并创建prototype对象。这就是它具有frog属性的原因。

现在,您可能想知道为什么第一种情况正常。因为,

color

不会将animal.prototype.color = 'Green'; 替换为其他对象,但它会突变(或增加,如果您愿意)animal.prototype对象。因此,animal.prototype的内部frog属性仍与[[Prototype]]对象相同。

答案 1 :(得分:0)

因为您要分配一个全新的对象。 prototype不是对象的[[Prototype]]new使用此属性设置内部属性。因此,prototype使用的new对象的引用与您稍后分配的对象不同。你不应该覆盖prototype属性,总是扩展它,就像在你的第一个例子中一样:

function Animal(){}
var frog = new Animal();
Animal.prototype.color = 'green';
console.log(frog.color); // green