2 回答
TA贡献1871条经验 获得超13个赞
目前(2020 年 10 月)这是正确的行为。
当你设置
class A { name }
这声明了一个类字段。这还不是一个标准,它是第 4 阶段的提案。它可能会改变,但不会太大。第 3 阶段是候选阶段,可能包括完成改进。
无论如何,根据提案的当前规范,您所看到的是正确的。任何没有初始化器的类字段都设置为undefined
. 发生这种情况是因为您在没有初始化程序的情况下调用了另一个类name
字段B
。父构造函数中发生的赋值将被覆盖。
以下是讨论此行为的提案的相关部分:
没有初始值设定项的字段设置为
undefined
公共和私有字段声明都会在实例中创建一个字段,无论是否存在初始化程序。如果没有初始值设定项,则该字段设置为
undefined
. 这与某些转译器实现有些不同,后者会完全忽略没有初始化器的字段声明。例如,在以下示例中,将生成属性为而非 的
new D
对象。y
undefined
1
class C { y = 1; } class D extends C { y; }在没有初始化器的情况下设置字段而不是擦除它们的语义
undefined
是字段声明提供可靠的基础以确保属性存在于创建的对象上。这有助于程序员将对象保持在相同的一般状态,这可以使推理变得容易,有时在实现中更可优化。
TA贡献2041条经验 获得超4个赞
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(`${this.name} barks.`);
}
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
如果您选中Use BabelJS / ES2015
SO 中代码段配置中的复选框,则您的代码不会出现任何问题。
class A {
name;
constructor(name){
this.name = name;
}
}
class B extends A {
name;
status;
constructor(name, status){
super(name);
this.status = status;
}
}
let a = new B('myClass',true);
console.log(a);
但是如果取消勾选...
class A {
name;
constructor(name){
this.name = name;
}
}
class B extends A {
name;
status;
constructor(name, status){
super(name);
this.status = status;
}
}
let a = new B('myClass',true);
console.log(a);
...相同的代码提供了您注意到的错误。
那么究竟是什么问题以及如何解决呢?无需name在子类中再次设置。如果不这样做,结果如下:
class A {
name;
constructor(name){
this.name = name;
}
}
class B extends A {
status;
constructor(name, status){
super(name);
this.status = status;
}
}
let a = new B('myClass',true);
console.log(a);
添加回答
举报