JS继承在构造函数中覆盖?

时间:2017-04-28 17:39:30

标签: javascript inheritance ecmascript-6 es6-class ecmascript-next

有人可以向我解释以下内容吗?

class BaseClass {
  prop = 88;
  constructor(){
    console.log("baseClass prop is ", this.prop);
  }
}
class DerivedClass extends BaseClass{
  prop = 83;
  constructor(){
    super();
    console.log("derivedClass prop is ", this.prop);
  }
}
new derivedClass();

,输出

baseClass prop is  88
derivedClass prop is  83

现在两个道具不应该相同(83)?因为一个道具覆盖了另一个道具? 我在这里弄错了吗?

3 个答案:

答案 0 :(得分:4)

您忘记了派生类的构造函数中的super()调用。

这样做是调用基类的构造函数。因此,基类的构造函数在派生类的构造函数之前运行完成。

表示执行基类的console.log语句时,prop变量仍为88。

答案 1 :(得分:2)

在构造函数执行时,类属性从类heirarchy的底部开始构造时初始化。

  • 在基类上,它们在开始时自动在构造函数内初始化。
  • 在子类上,它们会在super()之后立即运行。

逻辑基本上是

this.prop = 88;
console.log("baseClass prop is ", this.prop);

this.prop = 83;
console.log("derivedClass prop is ", this.prop);

因为班级是

class BaseClass {
  constructor(){
    this.prop = 88;
    console.log("baseClass prop is ", this.prop);
  }
}

class DerivedClass extends BaseClass {
  constructor(){
    super();
    this.prop = 83;
    console.log("derivedClass prop is ", this.prop);
  }
}

答案 2 :(得分:0)

您的代码无效。 ES6不是TypeScript,因此必须在构造函数内声明类属性。此外,对于类名,您应遵循 pascal case 而不是 camel case 的编码约定。这是正确的语法:

class BaseClass {
  constructor(){
    this.prop = 88;
    console.log("BaseClass prop is", this.prop);
  }
}
    
class DerivedClass extends BaseClass {
  constructor(){
    super();
    this.prop = 83;
    console.log("DerivedClass prop is", this.prop);
  }
}
    
new DerivedClass();

那么,为什么我们有88和83?实际上,当派生类通过super()调用基类时,this.prop为88并且您立即记录它。当super()执行结束时,this.prop变为83,但您之前的日志没有理由消失...

现在,如果出于某些原因需要私有属性,可以在构造函数之外声明它们,但是您需要IIFE(立即调用函数表达式):

const BaseClass = (() => {
  let prop = 88;

  class BaseClass {
    constructor(){
      console.log("BaseClass prop is", prop);
    }
  }

  return BaseClass;
})();
 
const DerivedClass = (() => {
  let prop = 83;
    
  class DerivedClass extends BaseClass {
    constructor(){
      super();
      console.log("DerivedClass prop is", prop);
    }
  }
  
  return DerivedClass;
})();
    
new DerivedClass();

如您所见,每个类都使用在其自己的范围内定义的prop变量。