and*_*rew 35 javascript constructor class this ecmascript-6
我在下面遇到了JavaScript(ES6)的问题
class A{
constructor(){
this.foo();
}
foo(){
console.log("foo in A is called");
}
}
class B extends A{
constructor(){
super();
this.foo();
}
foo(){
console.log("foo in B is called");
}
}
Run Code Online (Sandbox Code Playgroud)
我期待的是
foo in A is called
foo in B is called
Run Code Online (Sandbox Code Playgroud)
但事实上确实如此
foo in B is called
foo in B is called
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过简单地添加super.foo()B类的foo函数来解决这个问题
class B extends A{
constructor(){
super();
this.foo();
}
foo(){
super.foo() // add this line
console.log("foo in B is called");
}
}
Run Code Online (Sandbox Code Playgroud)
但想象一下类似的情景:
Child必须覆盖父项的功能才能执行一些额外的工作,并阻止外部访问能够访问原始功能.
class B extends A{
constructor(){
super();
this.initBar();
}
foo(){
super.foo();
this.bar.run(); //undefined
console.log("foo in B is called");
}
initBar(){
this.bar.run = function(){
console.log("bar is running");
};
}
}
Run Code Online (Sandbox Code Playgroud)
在父母的建设中,似乎this仍然指向孩子.这就是为什么我不能达到父母的.BAAfoo
如何this调用构造函数链中被子进程覆盖的父版本函数?
或者在这样的场景中有没有更好的解决方案?
编辑
因此,在阅读答案后,主要问题变为 -
它是气馁放initialize helpers或setter functions在JavaScript构造,因为孩子们有机会超越他们?
为了更清楚地澄清情况:(对不起我之前的坏例子:()
class A{
constructor(name){
this.setName(name);
}
setName(name){
this._name = name;
}
}
class B extends A{
constructor(name){
super(name);
this._div = document.createElementById("div");
}
setName(name){
super.setName(name);
this._div.appendChild(document.createTextNode(name));
}
}
new B("foo")
Run Code Online (Sandbox Code Playgroud)
this._div会的undefined.
这是一个坏主意,因为孩子能够覆盖这个功能吗?
class A{
constructor(name){
this.setName(name); // Is it bad?
}
...
}
Run Code Online (Sandbox Code Playgroud)
所以我不应该像在Java,C++中那样使用initialize helpers或setter functions构造函数......?
我必须手动调用这样的东西new A().init()来帮我初始化东西吗?
jfr*_*d00 18
您似乎在错误的观念下操作,即有两个对象,A并且B当您在派生类的构造函数中时B.事实并非如此.只有一个对象.无论A和B贡献的属性和方法的一个对象.this构造函数中的值将与在构造B函数A中创建B类对象时的值相同.
ES6类语法只是使用原型用于对象类型的ES5方法的糖,事实上,原型仍然在封面下使用.因此,当您foo像在类B中那样在派生类中定义方法时,它仍然会分配给原型,并且该赋值将覆盖来自父定义的原型上可能已存在的任何同名方法.这就是为什么this.foo()指的是B级版本foo.如果您想要达到A类的版本foo,那么您将手动指定使用,super因为您似乎已经知道.
至于你的具体问题:
在父母A中构建时,这似乎仍然指向孩子B.这就是为什么我无法达到父母A的foo.
子B和父A不是单独的对象.父A和子B都有一个对象引用.父A和子B的方法或构造函数将看到完全相同的值this.
如何让它调用在构造函数链中被子进程覆盖的父版本函数?
您可以super直接引用父方法,就像您已经知道的那样.
或者在这样的场景中有没有更好的解决方案?
super 是解决方案.
仅供参考,这是关于ES6课程的一个非常好的讨论,包括如何super工作:ECMAScript 6中的类(最终语义).第4.4节似乎与您的问题/理解特别相关.
| 归档时间: |
|
| 查看次数: |
43978 次 |
| 最近记录: |