下面是我为了解Function.prototype
而编写的示例JS代码<script>
function Foo() {
}
Foo.prototype = {
a: 9
};
var x = new Foo();
var y = new Foo();
console.log('x : ' + x.a + '\n');
console.log('y : ' + y.a + '\n');
x.a = 1;
console.log('x : ' + x.a + '\n');
console.log('y : ' + y.a + '\n');
</script>
我原以为执行上面的代码会导致输出
x:9 y:9 x:1 y:1
但实际输出是
x:9 y:9 x:1 y:9
有人可以解释为什么最后一个console.log打印9而不是1。
答案 0 :(得分:3)
x.a = 1;
不会更改prototype属性。它只为x
分配了一个新的“本地”属性,它隐藏了原型上定义的属性。
x.a === 1; //true because x.a === 1;
y.a === 9; //true because y.__proto__.a === 9;
您可以使用Foo.prototype.a = 1;
更改prototype属性。但是让我这样说:这种原型的使用至少是不常见的。通常,原型包含方法,而不包含实例之间共享的属性。对象的属性,通常在实例本身上定义。定义(或模拟)静态属性的一种常用方法如下:
Foo.a = 9;
然后,每当您想要使用或更改它时,您都可以简单地参考Foo.a
。
答案 1 :(得分:2)
因为x和y是单独的实例。您可以将变量x和y设置为相同的实例
<script>
function Foo() {
}
Foo.prototype = {
a: 9
};
var x = new Foo();
var y = x;
// the same is:
// var x, y;
// x = y = new Foo();
console.log('x : ' + x.a + '\n');
console.log('y : ' + y.a + '\n');
x.a = 1;
console.log('x : ' + x.a + '\n');
console.log('y : ' + y.a + '\n');
</script>
写下你的期望。
答案 2 :(得分:2)
您只是在对象的一个实例('x')上更改属性,而不是在原型上。
要使原型继承起作用,您必须将其设置在原型对象本身上,然后两个实例都将进行更改。
<script>
function Foo() {
}
Foo.prototype = {
a: 9
};
var x = new Foo(); // x.a === 9
var y = new Foo(); // y.a === 9
console.log('x : ' + x.a + '\n'); // === x: 9
console.log('y : ' + y.a + '\n'); // === y: 9
x.a = 1; // changed only for the 'x' instance
console.log('x : ' + x.a + '\n'); // === x: 1, because you changed it
console.log('y : ' + y.a + '\n'); // y: 9, because it inherited from the prototype.
</script>
如果您希望两个实例(实例x和实例y)都具有=== 9,那么您需要修改原型。
Foo.prototype = { a: 1 };
var x = new Foo(); // x.a === 1
var y = new Foo(); // y.a === 1
修改对象的实例不会修改原始对象的原型,只修改它的特定实例。