【问题标题】:Javascript prototype inheritance over multiple prototypesJavascript 原型继承于多个原型
【发布时间】:2019-09-11 09:49:03
【问题描述】:

当这种继承在多个对象之间延伸时,我在 javascript 原型继承方面遇到了一些问题:我肯定做错了什么,但目前我不明白是什么。

在扩展已经扩展原型的原型时,整个 Prototype 的继承系统似乎丢失了可用方法。

一个例子:

考虑以下对象

  • 对象 A
    • 具有扩展功能 ab 的原型
    • 带有扩展功能的原型 cd
  • 对象 B
    • 扩展 A
  • 对象 C
    • 扩展 B
    • 带有扩展函数ef的原型
  • 对象 D
    • 扩展 C

这里是这些对象的一个​​示例,正如我所定义的那样:

对象 A

function A () {
    this.someproperty = someValue;
}

A.prototype.ab = function () {
    // does something
}

A.prototype.cd = function () {
    // does something
}

对象 B

function B () {
    A.call(this);

    this.someOtherProperty = someValue;
}

B.prototype = A.prototype;
B.prototype.constructor = B;

对象 C

function C () {
    B.call(this);
}

C.prototype = B.prototype;
C.prototype.constructor = C;

C.prototype.ef = function () {
    // does something
}

对象 D

function D () {
    C.call(this);

    this.someOtherProperty = someValue;
}

D.prototype = C.prototype;
D.prototype.constructor = D;

鉴于上面的示例,我希望将变量初始化为“new D”,这样的变量应该具有可用的方法 ab、cd 和 ef,可通过

访问
  • variable.ab()
  • 变量.cd()
  • variable.ef()

似乎所有这些都是未定义的。

请考虑如果我初始化“new B”而不是:

  • 变量.ab()
  • variable.cd()

已定义并有效

是我做错了什么还是原型继承不能在多个对象上过度延伸?

谢谢!

【问题讨论】:

  • @mbojko 的回答应该在下面起作用。你如何检查new D() 的属性?例如Object.keys(new D()) 会给你somePropertysomeOtherProperty 因为它们属于实例,但方法不会也不会列出。 console.log((new D()).ab) 仍然应该给你一个函数参考。
  • 今后,请不要以使现有答案无效的方式编辑问题。请考虑回滚您的编辑并接受解决问题的答案。
  • 再次检查,@mbojko 答案是正确的修复,ES6 语法也正常工作。谢谢大家的支持

标签: javascript


【解决方案1】:
B.prototype = A.prototype;

这不是继承,而是覆盖:A.prototypeB.prototype 成为同一个对象。应该是

B.prototype = Object.create(A.prototype);

【讨论】:

  • 感谢您的回复。我也试过这个,并且会更新我的主要答案,但结果是一样的:当实例化一个新的 D 时,A 的方法是未定义的
  • @Mith84 很高兴了解它在底层是如何工作的,但是如果您要使用这种继承,我建议您使用class 语法。这样就可以解决诸如在没有new 的情况下调用您的构造函数之一的问题。
  • @EuanSmith 使用 ES6 语法然后解决问题?
  • 是的class B extends A {...}MDN
  • 我再次检查:原型扩展确实工作正常
【解决方案2】:

这是用 ES6 类重写的代码。 @mbojko 的回答是非常正确的(所以请接受这个而不是这个,因为@mbojko 直接回答了你的问题),但是如果你要使用这种深层次的类继承(很多人会争辩说你不应该- 对于一些问题,我倾向于认为这是正确的方法,但你当然需要谨慎)我建议改用 ES6 类 - 更清晰的语法和更多的防范错误使用。

class A{
  constructor (){
    this.someproperty = 0;
  }

  ab(){
    //...
    return "called ab method"
  }
  cd(){
    //...
  }
}

class B extends A{
  constructor(){
    super();
    this.someOtherProperty = 1;
  }
}

class C extends B{
  ef(){
    //...
  }
}
class D extends C{
  constructor(){
    super();
    this.someOtherProperty = 2;
  }
}

const d=new D();
console.log(d.ab());

【讨论】:

    猜你喜欢
    • 2010-09-28
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2021-11-14
    相关资源
    最近更新 更多