【发布时间】:2018-03-16 03:42:40
【问题描述】:
Javascript ES6(节点 8.4.0 和最新的 chrome 和最新的 Firefox)
我期待
class Parent {
init(){
console.log("Parent init") ;
this._surname = "McClass" ;
}
constructor() {
console.log("Parent constructor") ;
this.init();
}
get surname(){
return this._surname ;
}
}
class Child extends Parent {
init(){
console.log("Child init") ;
}
constructor() {
super();
console.log("Child constructor") ;
this.init();
}
}
var child = new Child() ;
console.log(child.surname);
给出以下输出;
Parent constructor
Parent init
Child constructor
Child init
McClass
(这是可比较的 C++ 代码给出的)
唉,我明白了;
Parent constructor
Child init
Child constructor
Child init
undefined
我是不是做错了什么,或者这是正确的预期行为,如果是这样,如何证明是合理的?
编辑;
请参阅下面的 MinusFour 回答,了解如何实现我正在尝试做/期望的事情。
至于为什么观察到的输出是“正确”的行为和合理的;
正如 Bergi 指出的(在 cmets 中),js 中对对象方法的所有调用实际上都是“虚拟的”(添加到对象原型继承链中的该名称的最后一个方法是第一个找到并因此执行的)。事实证明,调用在类构造上下文中仍然有效。
C++ 在构造过程中不应用虚方法行为,但 Java 再次应用,并且您在可比较的 Java 代码中获得相同的输出(如上),因此观察到的行为有先例。
【问题讨论】:
-
我不会在 child 中覆盖
init,只需将其称为其他名称。 -
@smnbbrv ,您能否详细说明或提供指向源的链接,解释为什么它是正确的或将这种行为定义为正确的?
-
@MinusFour,但是如果我从第 3 方类继承子类而不知道我正在使用父类中使用的名称会发生什么 - 然后我会得到我什至可能没有意识到正在发生的意外行为。
-
你为什么使用什么都不做的getter?如果您只想拥有一个点可访问属性,请添加它。如果您稍后改变主意,您可以在不更改调用代码的情况下重构为 getter。
-
JavaScript 中没有“私有”属性/方法的概念。一切都是公开的。用其他语言扩展类时,你不知道公共方法吗?
标签: javascript class inheritance ecmascript-6 overriding