访问超类上的类字段 [英] Accessing a class field on a superclass
问题描述
我有一个包含以下代码的文件:
class Animal {
doSomething = () => {
return 'Hi.';
};
}
class Dog extends Animal {
doSomething = () => {
return super.doSomething() + ' Woof!';
};
}
console.log(new Dog().doSomething());
注意:尝试运行上面的代码段可能无法正常工作,因为我不知道如何使用我的Babal设置来设置它.
无论如何,当我使用Babel编译它并在Node中运行它时,出现以下错误:
/Users/elias/src/classFieldTest/build/classFieldTest.js:15
return super.doSomething() + ' Woof!';
^
TypeError: (intermediate value).doSomething is not a function
at Dog.doSomething (/Users/elias/src/classFieldTest/build/classFieldTest.js:15:26)
at Object.<anonymous> (/Users/elias/src/classFieldTest/build/classFieldTest.js:21:23)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
我使用的是预设为stage-2
的Babel 6.26.0和Node 8.11.1.如果有人在意,我可以显示我正在使用的命令.
为什么会这样?我猜想super
不能用于访问类字段,但是我应该怎么做?如果我将Animal
的doSomething
方法更改为传统方法(doSomething() { return 'Hi.'; }
),则可以使用,但是我宁愿避免使用传统方法,而是用它们重新定义this
的方式以及它引起的所有混乱.>
有什么方法可以访问超类的类字段?
为什么会这样?我猜想super不能用于访问类字段
是的.类字段是实例属性,但是super
尝试访问超类的原型对象上的属性.您的Animal
类根本没有doSomething
方法-相反,每个Animal
对象都有一个包含绑定函数的属性.
但是我该怎么办?如果我将其更改为传统方法,则可以使用
是的,您应该做到这一点.方法和super
就是这样.
避免箭头功能在不需要它们时,尤其是类属性中的箭头函数可能不如我们想象的那么大.
有什么方法可以访问超类的类字段?
是-它是一个实例属性,您可以在覆盖它之前在其构造函数中对其进行访问:
class Animal {
constructor() {
this.doSomething = () => {
return 'Hi.';
};
}
}
class Dog extends Animal {
constructor() {
super();
const superDoSomething = this.doSomething;
this.doSomething = () => {
return superDoSomething() + ' Woof!';
};
}
}
或者,使用类字段proposal而不使用显式构造函数:
class Animal {
doSomething = () => {
return 'Hi.';
}
}
class Dog extends Animal {
doSomething = (superDoSomething => () => {
return superDoSomething() + ' Woof!';
})(this.doSomething)
}
I have a file with the following code:
class Animal {
doSomething = () => {
return 'Hi.';
};
}
class Dog extends Animal {
doSomething = () => {
return super.doSomething() + ' Woof!';
};
}
console.log(new Dog().doSomething());
Note: trying to run the snippet above probably won't work because I can't figure out how to make it use my Babal settings.
Anyway, when I compile it using Babel and run it in Node, I get the following error:
/Users/elias/src/classFieldTest/build/classFieldTest.js:15
return super.doSomething() + ' Woof!';
^
TypeError: (intermediate value).doSomething is not a function
at Dog.doSomething (/Users/elias/src/classFieldTest/build/classFieldTest.js:15:26)
at Object.<anonymous> (/Users/elias/src/classFieldTest/build/classFieldTest.js:21:23)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
I am using Babel 6.26.0 with the stage-2
preset, and Node 8.11.1. I can show the commands I'm using if anyone cares.
Why is this happening? I am guessing that super
can't be used to access a class field, but what am I supposed to do about this? If I change the doSomething
method of Animal
to a traditional method (doSomething() { return 'Hi.'; }
), it works, but I would rather avoid traditional methods, with the way they redefine this
and all the confusion it causes.
Is there any way to access a class field of a superclass?
Why is this happening? I am guessing that super can't be used to access a class field
Yes. Class fields are instance properties, but super
tries to access properties on the superclass' prototype object. Your Animal
class simply doesn't have a doSomething
method - instead, every Animal
object has a property that contains a bound function.
but what am I supposed to do about this? If I change it to a traditional method, it works
Yes, you are supposed to do exactly that. This is how methods and super
work.
Avoid arrow functions when you don't need them, and especially when they don't work. Also have a look at Arrow Functions in Class Properties Might Not Be As Great As We Think.
Is there any way to access a class field of a superclass?
Yes - it is an instance property, and you can access it in your constructor before overwriting it:
class Animal {
constructor() {
this.doSomething = () => {
return 'Hi.';
};
}
}
class Dog extends Animal {
constructor() {
super();
const superDoSomething = this.doSomething;
this.doSomething = () => {
return superDoSomething() + ' Woof!';
};
}
}
Alternatively, with the class fields proposal and no explicit constructor:
class Animal {
doSomething = () => {
return 'Hi.';
}
}
class Dog extends Animal {
doSomething = (superDoSomething => () => {
return superDoSomething() + ' Woof!';
})(this.doSomething)
}
这篇关于访问超类上的类字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!