Javascript子类方法未覆盖父类方法

时间:2018-07-18 11:14:56

标签: javascript ecmascript-6 ecmascript-5

我正在尝试从父类中重写一个方法,但是存在一些问题。

下面是我正在尝试的方案的代码段。

class Parent {
add = () => {
      console.log('Parent method');
}
}
class Child extends Parent {
add () {
console.log('Child Method');
 }
}
// Creating an instance
const child = new Child();
child.add();

它正在调用Parent方法add,因为它是箭头函数,有人可以解释为什么会这样。如果我将父函数设为简单的javascript方法,则子函数可以覆盖。

其他详细信息

  1. 我无权访问Parent,因为它是图书馆的一部分。
  2. 我无法将子类方法设为实例属性(箭头功能)   ,原因在于 为孩子(孩子的孩子)编写的规范,如果我们使用箭头 功能,我们将无法调用超级。
  3. 子功能名称不能重命名。

2 个答案:

答案 0 :(得分:1)

父级add是一个实例属性,它使子级的class方法(该实例的原型的一部分)黯然失色。有点hacking,但是您可以在构造函数中重命名和删除class属性:

class Parent {
  add = () => {
    console.log('Parent method');
  }
}
class Child extends Parent {
  constructor() {
    super();
    this.parentAdd = this.add;
    delete this.add;
  }

  add() {
    console.log('Child Method');
    this.parentAdd(); // if you need call the parent's method
  }
}

const child = new Child();
child.add();

答案 1 :(得分:1)

这是one of few reasons why arrow methods aren't convenient。它们限制了类的扩展和测试方式。

Class fields(箭头方法是)是构造函数代码的语法糖:

class Parent {
  constructor() {
    this.add = () => {...};
  }
}

只有另一个arrow方法可以覆盖父arrow方法,因为它们是在类构造函数中定义的,而不是在类原型上定义的:

class Child extends Parent {
  add = () => {
    /* no super.add here because add is not prototype method */
  }
}

如果打算使用super.add,则解决方法是存储父方法:

class Child extends Parent {
  superAdd = this.add;
  add = () => {
    this.superAdd();
  }
}

请注意,由于这是构造函数代码的语法糖,因此superAddadd的定义顺序很重要。