我在此代码段中使用原型继承:
function SuperType() {
this.colors = ["red", "blue", "green"];
this.x = 1;
}
function SubType() {}
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("black");
instance1.x = 2;
//alert(instance1.colors); // "red,blue,green,black"
//alert(instance1.x); // 2
var instance2 = new SubType();
alert(instance2.colors); // "red,blue,green,black"
alert(instance2.x); // 1
我希望输出为
"red,blue,green"
1
或
"red,blue,green,black"
2
但我明白了:
"red,blue,green,black"
1
为什么?
答案 0 :(得分:4)
问题在于:
SubType.prototype = new SuperType();
因为SuperType
构造函数将.colors
数组放在对象上,并且因为该对象用作.prototype
的{{1}},所以SubType
数组在所有.colors
个实例之间共享。
相反,在设置继承时不要调用构造函数,但执行在SubType
构造函数中调用它。
SubType
function SubType() {
SuperType.apply(this, arguments);
}
SubType.prototype = Object.create(SuperType.prototype);
没有相同问题的原因是数字不可变,所以当您尝试修改它时,会直接在对象上创建新的.x
&# 39;重新使用而不是改变x
。
答案 1 :(得分:1)
写作时
instance1.x = 2;
您要向x
添加名为instance1
的新媒体资源。
instance1
的原型,您可以使用instance1.__proto__
查找,不受影响。 instance1.__proto__.x
的值仍为1.
当您参考
时instance1.x
对象自己的属性instance1.x
优先于原型的属性instance1.__proto__.x
。我们说x
上的instance1
阴影 x
上的instance1.__proto__
。
当JavaScript评估instance1.x
时,它会在升级原型链之前检查instance1
的自身属性。因此,您看到的是自己的属性instance1.x
的值。
但是当你写作
instance1.colors
对象instance1
没有名为colors
的属性。因此,JavaScript会查看其原型。它找到instance1.__proto__.colors
并返回其当前值。
当你写
时instance1.colors.push("black");
您没有向instance1
添加新属性。您只是修改了数组instance1.__proto__.colors
。具有相同原型的所有对象将看到相同的colors
值,除非它们具有隐藏colors
的属性。
在下面的代码片段中,我创建了第三个对象c
,它定义了一个名为colors
的自有属性,它隐藏了原型的属性c.__proto__.colors
。
var c = new SubType();
c.colors = [ 'orange', 'purple' ];
自有属性c.colors
的值是与原型属性c.__proto__.colors
不同的数组。没有自己的属性colors
的对象将继续看到原型colors
的值。
function SuperType() {
this.colors = ["red", "blue", "green"];
this.x = 1;
}
function SubType() {}
SubType.prototype = new SuperType();
var a = new SubType();
a.colors.push("black");
a.x = 2;
message('a.colors: ' + a.colors.join(', ')); // red, blue, green, black (prototype's colors)
message('a.x: ' + a.x); // 2 (own property x)
message('a.__proto__.x: ' + a.__proto__.x); // 1 (prototype's x)
var b = new SubType();
message('b.colors: ' + b.colors.join(', ')); // red, blue, green, black (prototype's colors)
message('b.x: ' + b.x); // 1 (prototype's x)
var c = new SubType();
// Make an own property, colors, that shadows the prototype's property.
c.colors = [ 'orange', 'purple' ];
message('c.colors: ' + c.colors.join(', ')); // orange, purple (own property colors)
message('b.colors: ' + b.colors.join(', ')); // red, blue, green, black (prototype's colors)
message('a.colors: ' + a.colors.join(', ')); // red, blue, green, black (prototype's colors)
function message(line) {
document.getElementById('messageBox').innerHTML += line + '<br>';
}
body {
font-family: sans-serif;
}
<div id="messageBox"></div>
答案 2 :(得分:0)
当您运行XHRCallToTheRestService()
.then(function(result){
//Hide status bar, data is back
});
readMyStatus()
.then(function(status){
if(status == "finished"){
//Do nothing
} else{
readMyStatus();
}
});
时,您正在使用一种方法来修改对象(颜色列表);所以指向该对象的所有变量都会看到变化。
当您使用.push("black")
时,您正在替换该一个变量的值,因此其他变量仍然可以指向原始值。