所以我上下阅读了JavaScript中的组合继承主题。我认为目的是使用原型链来继承属性和方法 - 并使用构造函数窃取来继承实例属性。
我提供了一个令我难以置信的例子,并阻止我完全理解这个概念。
简而言之,我创建了一个SuperColors父函数,它通过SubColors构造函数方法中的call()执行将其属性传递给SubColors。据我了解,这应该允许实例(instance1)拥有自己的颜色属性,如我所示。
这是古怪的部分。我删除了instance1的颜色属性。这应该意味着当我推动新颜色时,他们应该将SuperColors颜色属性操纵为完整的彩虹。然后当我创建一个SubColors的新实例(instance2)时,他们应该继承彩虹。
他们不是。如果我们在console.log()中查看instance2,颜色会被实例化为“红色,橙色,黄色”,即使我们也可以清楚地看到SuperColor的颜色属性具有整个彩虹。
这对我没有意义 - 我是不正确地理解原型继承还是这是一种奇怪的语言怪癖?
function SuperColors() {
this.colors = ["red", "orange", "yellow"];
}
SuperColors.prototype.sayColors = function () {
alert("SuperColors " + this.colors);
};
function SubColors() {
//inherit properties
SuperColors.call(this);
}
// inherit methods
SubColors.prototype = new SuperColors();
SubColors.prototype.sayRainbow = function () {
alert(this.colors + "a whole rainbow!");
};
// create an instance of SubColors
var instance1 = new SubColors();
// push colors to colors property on instance
instance1.colors.push("green", "blue", "purple");
alert(instance1.colors); // "red, orange, yellow, green, blue, purple"
instance1.sayColors(); // "SuperColors red,orange,yellow,green,blue,purple";
// delete instance of colors
delete(instance1.colors);
console.log(instance1);
// this should manipulate SuperColor's constructor of colors
instance1.colors.push("green", "blue", "purple");
// instantiate a new SubColor object that should inherit SuperColor's entire rainbow
var instance2 = new SubColors();
alert(instance1.colors);
alert(instance2.colors); // WHY ISN'T THIS THE ENTIRE RAINBOW? It should have been instantiated with SuperColor's modified colors.
console.log(instance2); // Shows that SuperColors.colors has the rainbow, but the instance has only 3 colors?
答案 0 :(得分:2)
// this should manipulate SuperColor's constructor of colors delete instance1.colors; instance1.colors.push("green", "blue", "purple");
不完全是。它不会操纵SuperColor
构造函数,而是SubColor.prototype
(一个SuperColor
实例),instance1
从中继承其.colors
属性(现在它没有自己的了。)
// instantiate a new SubColor object that should inherit SuperColor's entire rainbow var instance2 = new SubColors();
不,继承过程中没有任何改变。 instance2
仍然SubColor.prototype
继承instance1
。并且仍在新实例上调用SuperColor
构造函数...
alert(instance2.colors); // WHY ISN'T THIS THE ENTIRE RAINBOW?
...它创建了一个全新的数组,该数组被分配给新实例的新的自己的 .colors
属性!那个新数组是你正在访问的数组,它从未被任何东西修改过。
如果你愿意
delete instance2.colors;
然后你可以在做
时看到SubColor.prototype.colors
alert(instance2.colors);
答案 1 :(得分:1)
删除instance2.colors
。然后你会得到整个彩虹:
delete instance2.colors;
alert(instance2.colors);
请参阅演示:http://jsfiddle.net/ZKAZf/1/
您应该阅读以下有关JavaScript继承的帖子:
答案 2 :(得分:0)
我认为这取决于此:
function SubColors() {
//inherit properties
SuperColors.call(this);
}
您在此处执行的操作是SuperColors
,但使this
引用您正在创建的SubColors
实例。在SuperColors
内部,SubColors
实例会获得自己的colors
属性 - 会隐藏原型上的colors
属性。
因此,当某些内容试图在colors
实例上查找SubColours
时,它会在该实例上找到,并且不会再查找原型链。当您在colors
上删除instance1
时,instance1.colors
的后续查找现在必须查找原型链以查找SuperColors
版本,但在创建instance2
时,您将再次在colors
实例上创建SubColors
,该实例会隐藏SuperColors
上的版本。
如果您delete instance2.colors
,您会看到instance2.colors
现已解析为colors
的版本,而且整个彩虹。