如果我只使用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'
答案 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