【问题标题】:How to access subclass from parent in ES6? [duplicate]如何在 ES6 中从父类访问子类? [复制]
【发布时间】:2018-06-30 15:21:13
【问题描述】:

我有一个如下所示的基类:

class Speaker {
  sayHi() {
    if (this.isLoud) {
      console.log('HI');
    } else {
      console.log('hi');
    }
  }
}

还有一个看起来像这样的子类:

class LoudSpeaker extends Speaker {
}
LoudSpeaker.isLoud = true;

... 最后一行是尝试在 ES6 中创建类变量。问题是当我实例化LoudSpeaker 并调用sayHi 时,isLoud 变量是未定义的。是否可以从父类访问子类的类变量?

【问题讨论】:

  • 您错过了添加class LoudSpeaker extends Speaker吗?
  • 好吧,你可以改用模板模式,并有一个子类可以覆盖的方法?
  • @MaazSyedAdeeb 是的,感谢您指出这一点。我刚刚更正了。
  • LoudSpeaker.isLoud - 这是在“class”对象上设置属性,而不是实例。 this.isLoud 正在尝试访问“实例”的属性。如果方法访问了LoudSpeaker.isLoud 属性,则代码“可以工作”。
  • @edpaez 就该方法而言,将有几十个具有基本相同功能的子类。想象一下RedLoudSpeakerBlueLoudSpeaker 等。我试图避免每次都重写它们......

标签: javascript ecmascript-6


【解决方案1】:

this.isLoudLoudSpeaker.isLoud 不同。第一个引用实例变量,第二个引用 LoudSpeaker 构造函数的属性,其他语言将其称为类变量或静态属性。在 Javascript 中,您不能使用 this.isLoud 来引用类变量。

要覆盖子类中实例变量isLoud 的值,您可以在构造函数中设置它的值。

class Speaker {
  constructor() {
      this.isLoud = false;   // set default value
  }
  sayHi() {
    if (this.isLoud) {
      console.log('HI');
    } else {
      console.log('hi');
    }
  }
}

class LoudSpeaker extends Speaker {
   constructor() {
       super();
       this.isLoud = true;    // override to set our own value
   }
}

如果你真的希望isLoud 属性是一个类设置一次并且不再设置的东西,那么你可以在原型上设置它,然后你可以在实例中使用this.isLoud 引用它:

class Speaker {
  sayHi() {
    if (this.isLoud) {
      console.log('HI');
    } else {
      console.log('hi');
    }
  }
}

Speak.prototype.isLoud = false;           // set default value

class LoudSpeaker extends Speaker {
}

LoudSpeaker.prototype.isLoud = true;      // override for this class

这通常不会在 Javascript 中完成,因为如果您设置 this.isLoud = whatever,那么它会设置一个“自己的”属性,并且该属性将成为特定于该实例的实例属性,这可能会非常令人困惑并导致错误。所以,一般不会这样做。但是,如果您在原型上初始化值,而不是在实例上设置它,因此您只使用x = this.isLoud 读取它的值,那么它的行为就像一个可通过this 访问的类变量。

在 ES6 wiki 中有关于这个主题的讨论。有关详细信息,请参阅ES6 class variable alternatives,因为此功能故意被排除在 ES6 类语法之外,这就是为什么它在这里实现为在构造函数中设置的常规实例变量或直接在原型上设置的属性(而不是通过类语法) .

【讨论】:

  • 这似乎不是 OP 想要的:“@user2864740 对,我想知道是否有办法从父类访问子类变量。它不应该是实例变量。”
  • @2pha - 有趣的是,您应该提到这一点,因为在看到您的评论之前,我刚刚完成了添加该内容的编辑。是的,通常会在父构造函数中设置一个默认值。
  • @Rob - 嗯,这目前不是 Javascript 的一个特性,可能部分与它的对象是基于原型的事实有关。 ES6 类语法只是填充原型的一种语法便利。 ES6 语法的基本实现并没有真正改变太多(尽管新语法确实更方便)。
  • @Rob 我完全可以理解,我花了很长时间才理解来自 Java 类背景的原型继承。但我在 javascript 类出现之前就已经这样做了,所以可能没有那么混乱
  • @Rob - 我将原型想法添加到我的答案中。
猜你喜欢
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 2021-12-03
相关资源
最近更新 更多