是否可以在 child class ES 2015 的实例中调用重写方法?

Is it possible to call an overridden method in an instance of child class ES 2015?

我最近在看技术面试问题时看到了一个类似的问题,这让我开始思考 object 在 JavaScript 中更普遍的继承。

这是一些简单的代码:

class Car {
  constructor(make,model) {
    this.make = make
    this.model = model
  }

  emitsCarbon() {
    return true
  }

}

class Hybrid extends Car {
  constructor(...args) {
    super(...args)
  }
  emitsCarbon() {
    return false
  }
}

let car1 = new Hybrid('toyota', 'prius')

car1.emitsCarbon() // returns false

我很好奇的是,是否有一种方法可以在child class?

的实例

我的假设是不,一旦它被覆盖,我将不得不在 car1 的实例中再次覆盖该方法,以便在调用函数时将其设置为 return true。

我想填补的知识不足是:在JavaScript中是否可以参考class继承中的备份级别并查看所有parentclass 属性(方法等)给出了一个child class 的实例。看起来这在其他语言中是可能的(例如,java),但是,我对这些语言的经验不多。

最后,这是否有用,即是否应该更加小心地覆盖不应覆盖的属性,我不太确定。我认为那不应该。但是,更好地理解在 classes 和 class 继承层次结构中提升一个级别是很有用的。

这不是以下内容的副本:How to call a parent method from child class in javascript?

我理解 child class 中的 parent 方法的调用,但是,我不理解调用(如果可能的话,似乎不是) child 实例.

中的parent方法

我不敢相信这不是重复的,但我找不到它(所有现有的 Q/A 都处理旧式构造函数),所以...

只需使用super:

class A {
  foo () {
    return 0;
  }
}

class B extends A {
  foo () {
    return 1;
  }

  bar () {
    return super.foo();
  }
}

const b = new B();
b.foo() // 1
b.bar() // 0

有一些限制,使用super将不允许您修改只读属性。

有关详细信息,请参阅 MDN article

当您可以修改 child class.

时,另一个答案很有用

但由于原始 post 提到了“...instance of child class”,而不是 'given the child class',那么即使您无法使用 <ParentClass>.prototype.<methodName>.

修改 child class,也可以执行类似的操作

class A {
  foo () {
    return 0;
  }
}

class B extends A {
  foo () {
    return 1;
  }
}

let b = new B();
console.log(b.foo()); // 1
console.log(A.prototype.foo()); // 0

对于需要 this 上下文的方法,使用 call 调用。

class A {
  constructor(f) {
    this.f = f;
  }

  foo(ff) {
    return this.f + ff + 1;
  }
}

class B extends A {
  foo(ff) {
    return this.f + ff + 2;
  }
}

let b = new B(10);
console.log(b.foo(5)); // 17
console.log(A.prototype.foo.call(b, 5)); // 16

当子级覆盖父级方法时,它将始终使用覆盖的版本,除非您不使用 'super' 关键字在子本身的方法定义中。

通过已经重写方法的子对象调用父方法是不可能的。

是JavaScript,所以你可以。反正没有 classes,只是原型继承加上一些语法糖。

你想叫哪一个:CaremitsCarbon 具体?那将是

Car.prototype.emitsCarbon.call(car1);

您对象的 class' 直系祖先 class' emitsCarbon 一般而言?

car1.__proto__.__proto__.emitsCarbon.call(car1);

(你不应该直接访问 __proto__,但除了一般的良好做法和指南之外,没有什么能真正阻止你。

此外,混合动力车确实会排放碳。只是一个旁注。