查看代码:
function A(){
}
var x = new A();
console.log(x.attr); // undefined
A.prototype.attr = 1;
console.log(x.attr); // 1
当我们调用new A()
且x没有属性attr
时内存被分配,但是在执行A.prototype.attr = 1;
之后,x具有属性attr
。
是否意味着x
已重新分配?
答案 0 :(得分:2)
不。 x
是A
的实例。最初尝试访问x.attr
时,其原型A
没有名为attr
的属性。因此,这等效于调用x.i_want_something_which_does_not_exist
并返回undefined
。但是,在分配A.prototype.attr
之后,A
的所有实例将共享该值。例如,
function A(){
}
var x = new A();
var y = new A();
document.write(x.attr+"<br>"); // undefined
document.write(y.attr+"<br>"); // undefined
A.prototype.attr = 1;
document.write(x.attr+"<br>"); // 1
document.write(y.attr+"<br>"); // 1
编辑:这是三个实例的示例:
function printValues(x, y, z){
document.write("x.attr="+x.attr+", y="+y.attr+", z.attr="+z.attr+"<br />"); // Although I strongly recomment you to never use document.write
// https://stackoverflow.com/questions/802854/why-is-document-write-considered-a-bad-practice
}
function A(){
}
var x = new A();
var y = new A();
var z = new A();
printValues(x, y, z);
A.prototype.attr = 1;
printValues(x, y, z);
y.attr = 2;
printValues(x, y, z);
产生:
x.attr=undefined, y=undefined, z.attr=undefined
x.attr=1, y=1, z.attr=1
x.attr=1, y=2, z.attr=1
请注意,在运行y.attr=1
之后,y.attr
的引用不同于x.attr
和z.attr
,它们仍然共享相同的引用。
答案 1 :(得分:2)
混乱是由原型继承引起的。 x本身没有属性 attr 。可以通过运行以下命令进行验证:
x.hasOwnProperty('attr')
这将返回 false 。
但是 x.attr 引用分配给 A.prototype 的 attr 属性。
要查看尝试控制台日志
x.__proto__
attr 属性将在此处显示。
答案 2 :(得分:0)
您只需将属性attr
添加到A
的原型对象中。当您调用x.attr
时,它首先尝试在x
自己的属性中找到它,如果找不到,请转到'A'的原型。
答案 3 :(得分:0)
感谢@Matheus Pitz。读完Prototypes in JavaScript之后,我得到了完美的答案。
A.prototype由A的所有实例共享。执行new A()
时,将创建A().__proto__
,并引用A.prototype
。因此,当我们将attr
添加到A.prototype
时,A
的所有实例都不会更改。
当我们更改实例的attr
时,它不会更改instance.__proto__.attr
,而是将attr
添加到实例。
请参见示例:
function A(){
}
var x = new A();
var y = new A();
A.prototype.attr = 1;
console.log(x.__proto__ === A.prototype) //true
console.log(y.__proto__ === A.prototype) //true
A.prototype.attr = 2;
document.write(x.attr+"<br>"); // 2
document.write(y.attr+"<br>"); // 2
x.attr = 3;
console.log(x.hasOwnProperty('attr')) //true,attr=3
console.log(x.__proto__) //attr=2
document.write(x.attr+"<br>"); // 3
document.write(y.attr+"<br>"); // 2