【问题标题】:How to deal with and discern inheritance conflicts in JavaScript?如何处理和辨别 JavaScript 中的继承冲突?
【发布时间】:2014-02-06 00:24:50
【问题描述】:

所以下面的代码反映了 JavaScript 中的伪经典继承。

function SynthOne() { // constructor 1
    this.sound1 = "piano";
};

function SynthTwo() { // constructor 2
    this.sound2 = "bass";
}

SynthOne.prototype = new SynthTwo; // overwrite constructor 1's prototype with constructor 2's
var synthsCombined = new SynthOne; // assign constructor 1 to variable

// this variable now has access to both constructors properties & methods

document.write(synthsCombined.sound1 + " ")
document.write(synthsCombined.sound2)

但是让我们改变一下,让 sound1sound2 变成简单的sound

我们还假设我真的想创建一个继承链来访问这两个“声音”,即使它们被命名为相同的东西。 JavaScript 社区中是否存在处理这种情况的模式或编码约定?还是我只是卡住了?

谢谢

【问题讨论】:

  • 你想用synthsCombined做什么,你期望什么“组合”?在继承中,子属性会影响父属性是完全正常的——这正是您想要的。也许“继承”不是您problem的解决方案。
  • 我没有将这段代码用于任何事情,它只是进入了我的脑海,我很好奇。我可以看到一种情况,至少您组合构造函数时没有意识到它们具有相似的属性/方法名称。我认为可能有一种我不知道的传统“方法”来处理这个问题。
  • 问题在于解决方案取决于现实世界的需求。可以/应该在从这些构造函数创建的所有对象之间共享属性的值吗?如果是这样,那么您可以获取原型链中的下一个对象,并获取该值。如果不是,那么一个对象显然不能同时分配两个值。您可能需要一个映射或值数组。再次,一切以实际情况为准。
  • 覆盖和扩展父函数包含在这个答案中:stackoverflow.com/a/16063711/1641941 最好使用 Object.create 或辅助函数来设置继承的原型部分,而不是创建 Parent 的实例

标签: javascript inheritance constructor


【解决方案1】:

子属性在原型链的上游隐藏同名属性。从技术上讲,您仍然可以像这样访问父属性:

Object.getPrototypeOf(synthsCombined).sound

或非标准:

synthsCombined.__proto__.sound

但这可能不是你想做的事情。如果您需要这两个值,请将它们命名为不同的名称。

【讨论】:

    【解决方案2】:

    这只是进入我的脑海,我很好奇的事情。我可以看到一种情况,至少您组合构造函数时没有意识到它们具有相似的属性/方法名称。

    你几乎不会从你不知道的属性集1的类继承。如果您对某些内容进行子类化,您通常希望使用更具体的值显式覆盖属性 - 这正是阴影的用途。

    如果您想扩展集合,您必须选择一个未分配的名称。在接口冲突的情况下(例如,在扩展实现时),这只是一个错误,基类或子类都需要更改它们的标识符。使用描述性名称会降低风险。

    遇到这种情况怎么办?

    如果不需要,请修复错误(这不是 JavaScript 特定的)。如果您故意选择了相同的属性名称,您可以通过手动使用Object.getPrototypeOf() 提升原型链来访问继承的值。

    [1]:说到属性和方法,因为它们只是 javascript 中的属性

    【讨论】:

      【解决方案3】:

      你可以给你的构造函数一个基础属性,它会从继承的构造函数中获取属性:

      function SynthOne() { // constructor 1
          this.base = {};
          this.sound = "piano";
      
          SynthTwo.call(this.base);
      };
      
      function SynthTwo() { // constructor 2
          this.sound = "bass";
      }
      
      SynthOne.prototype = Object.create(SynthTwo.prototype);
      var synthsCombined = new SynthOne; 
      console.log(synthsCombined.sound);         //piano
      console.log(synthsCombined.base.sound);    //bass
      

      但是从你想要完成的样子来看,也许继承对你来说不是正确的方法。创建一个通用的Synth 类和SynthCollection 类可能更有意义,以组合不同的Synths。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-01
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多