Javascript 是否可以在子类ES 2015的实例中调用重写的方法?
我最近在看技术面试问题时看到了一个类似的问题,这让我更普遍地思考JavaScript中的对象继承 下面是一些简单的代码:Javascript 是否可以在子类ES 2015的实例中调用重写的方法?,javascript,inheritance,es6-class,Javascript,Inheritance,Es6 Class,我最近在看技术面试问题时看到了一个类似的问题,这让我更普遍地思考JavaScript中的对象继承 下面是一些简单的代码: class Car { constructor(make,model) { this.make = make this.model = model } emitsCarbon() { return true } } class Hybrid extends Car { constructor(...args) { su
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
我想知道的是,是否有一种方法可以调用原始的emitsCarbon()
方法,该方法在子类的实例中返回true(来自父类)
我的假设是否定的,一旦它被重写,我将不得不在car1实例中再次重写该方法,以使其在调用函数时返回true
我想补充的知识不足是:在JavaScript中,是否可以引用类继承中的备份级别,并查看给定子类实例的所有父类属性(方法等)。在其他语言(例如java)中,这似乎是可能的,但是,我对这些语言没有那么多的经验
最后,这是否有用,也就是说,是否应该更加小心地覆盖不应该被覆盖的属性,我不太确定。我认为不应该。但是,更好地理解类和类继承层次结构中的向上移动是有用的
这不是以下内容的副本:
我理解子类中父方法的调用,但是,我不理解子实例中父方法的调用(如果可能的话,这似乎不是)。我不相信这不是重复的,但我找不到它(所有现有的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
将不允许修改只读属性
有关更多详细信息,请参阅。另一个答案适用于您何时可以修改子类 但是,由于最初的帖子提到了“…子类实例”,而不是“给定子类”,因此即使无法使用
.prototype.
修改子类,您也可以这样做
A类{
foo(){
返回0;
}
}
B类扩展了A类{
foo(){
返回1;
}
}
设b=新b();
console.log(b.foo());//1.
console.log(A.prototype.foo());//0
当子级重写父方法时,它将始终使用被重写的版本,除非在子级本身的方法定义中不使用'super'关键字通过已经覆盖父方法的子对象调用父方法是不可能的。
这是JavaScript,所以您可以。反正也没有类,只有原型继承和一些语法上的甜点 您想具体调用哪一个:
Car
的emitsCarbon
?那太好了
Car.prototype.emitsCarbon.call(car1);
您的对象的类“直接祖先类”emitsCarbon
car1.__proto__.__proto__.emitsCarbon.call(car1);
(您不应该直接访问\uuuuu proto\uuuuu
,但除了一般的良好实践和指南之外,实际上没有什么可以阻止您)
此外,混合动力车确实会排放碳。只是一个旁注。可能重复的我认为这是我正在寻找的正确答案,但是另一个答案显示了解决方法。是的,由于代码的糟糕设计,存在解决方法。但是您需要修改继承类中的方法定义。如果有一个真正的方法来实现上述目标,我很想了解它。PS我对JS了解不多。这真的很有帮助(我知道!我在这里读了很多答案,但没有用新语法直接回答这个问题)。假设这些类不能被修改(出于某些原因),是否可以在b的实例中指向原始类,或者Danish Shakel是正确的,它不再是可能的?我认为这是正确的,因为这是问题的核心。我想我理解了为什么不应该直接访问
\uuuu proto\uuuu
(第一次正确编写子类!)。你能指出我为什么不应该直接访问\uuuu proto\uuu
的参考资料/指南吗。还有,我知道!这就是为什么我选择这个示例,因为它需要被重写,例如,为了示例,我编写了错误的函数。MDN是一个很好的起点(被粉红色上的所有文本吓坏了):有趣的是,第一个代码段与……第一个代码段完全相同,这并不是我将其标记为正确的原因。第二段代码就是我想要的。重要的是通过子对象传递给父对象,而不仅仅是调用函数。第二个代码段通过指向子实例来调用父类中的函数来突出显示这一点。我很好奇孩子是否可以访问它,而不仅仅是调用父对象。因此,在我的示例中,它将是Car.prototype.emitsCarbon.call(car1)
,但这与简单地调用Car.prototype.emitsCarbon.call()
没有什么区别,还是我错了?当我在call方法中运行不传递参数的代码时,它仍然返回true。是的,这是正确的,正如我在第一个示例中所解释的,如果您的方法是有效静态的(需要nothis
context),则不需要call
。啊,我看到了两者之间的区别。非常感谢。这很有帮助,但不是我想要的。