【问题标题】:Javascript Combination Inheritance - Unexpected ResultJavascript 组合继承 - 意外结果
【发布时间】:2013-07-16 11:50:16
【问题描述】:

所以我已经阅读了关于 JavaScript 中组合继承的主题。我知道其目的是使用原型链来继承属性和方法——并使用构造函数窃取来继承实例属性。

我提供了一个让我难以理解的例子,让我无法完全理解这个概念。

简而言之,我创建了一个 SuperColors 父函数,该函数通过在 SubColors 构造方法中的 call() 执行将其属性传递给 SubColors。据我了解,这应该允许实例 (instance1) 拥有自己的颜色属性,正如我所展示的那样。

这是古怪的部分。我删除了 instance1 的颜色属性。这应该意味着当我推送新颜色时,他们应该将 SuperColors 颜色属性操作为完整的彩虹。然后,当我创建 SubColors 的新实例(instance2)时,它们应该继承彩虹。

但他们没有。如果我们查看 console.log() 中的 instance2,颜色被实例化为“Red,Orange,Yellow”,尽管我们可以清楚地看到 SuperColor 的 color 属性具有整个彩虹。

这对我来说没有意义——我是否错误地理解了原型继承,或者这是出乎意料的语言的奇怪怪癖?

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?

http://jsfiddle.net/ZKAZf/

【问题讨论】:

    标签: javascript


    【解决方案1】:
    // this should manipulate SuperColor's constructor of colors
    delete instance1.colors;
    instance1.colors.push("green", "blue", "purple");
    

    不完全是。它不会操纵SuperColor 构造函数,而是操纵SubColor.prototypeSuperColor 实例),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);
    

    【讨论】:

      【解决方案2】:

      删除instance2.colors。然后你会得到整个彩虹:

      delete instance2.colors;
      alert(instance2.colors);
      

      查看演示:http://jsfiddle.net/ZKAZf/1/

      您应该阅读以下有关 JavaScript 继承的文章:

      1. Aadit M Shah | Why Prototypal Inheritance Matters
      2. JavaScript inheritance and the constructor property
      3. Benefits of prototypal inheritance over classical?
      4. No ways to have class-based objects in javascript?

      【讨论】:

      • 但我不应该在创建新实例时对每个实例都这样做。问题更多的是为什么当 SuperColors 颜色属性明显是“红、橙、黄、绿、蓝、紫”时,为什么每个新实例都不用彩虹光谱进行实例化
      【解决方案3】:

      我认为是这样的:

      function SubColors() {
          //inherit properties
          SuperColors.call(this);
      }
      

      您在这里所做的是执行SuperColors,但使this 引用您正在创建的SubColors 实例。在 SuperColors 内部,SubColors 实例会被赋予其自己的 colors 属性 - 这会隐藏原型上的 colors 属性

      因此,当某些东西试图在您的 SubColours 实例上查找 colors 时,它会在该实例上找到 某些东西,并且不会进一步查找原型链。当您删除instance1 上的colors 时,随后查找instance1.colors 现在必须查找原型链以找到SuperColors 版本,但是当您创建instance2 时,您再次在@ 上创建colors 987654337@ 实例隐藏了SuperColors 上的版本。

      如果您delete instance2.colors,您将看到instance2.colors 现在解析为带有整个彩虹的colors 版本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-27
        • 2014-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-31
        相关资源
        最近更新 更多