Javascript:为什么在子类中声明属性会将超类中的同一属性覆盖为null
我的问题与理解类如何为属性赋值以及对象如何在Javascript中实例化有关。我想更多地了解这个过程是如何工作的 如果我创建两个类,其中第二个继承第一个Javascript:为什么在子类中声明属性会将超类中的同一属性覆盖为null,javascript,class,inheritance,Javascript,Class,Inheritance,我的问题与理解类如何为属性赋值以及对象如何在Javascript中实例化有关。我想更多地了解这个过程是如何工作的 如果我创建两个类,其中第二个继承第一个 class A { name constructor(name){ this.name = name } } class B extends A { name status constructor(name, status){ super(name)
class A {
name
constructor(name){
this.name = name
}
}
class B extends A {
name
status
constructor(name, status){
super(name)
this.status = status
}
}
然后创建一个类B的实例,当我将它打印到控制台时
x = new B('myClass', true)
console.log(x)
它显示名称变量未定义
B { name: undefined, status: true }
我很确定B中的name属性是在A中过度写入name属性,但为什么A构造函数不将新的name变量指定为传递给它的值呢?这个例子是借用的,以表明这种行为不应该发生
类动物{
建造师(姓名){
this.name=名称;
}
讲{
log(`${this.name}发出噪音。`);
}
}
狗类动物{
建造师(姓名){
super(name);//调用super类构造函数并传入name参数
}
讲{
log(`${this.name}barks.`);
}
}
设d=新狗('Mitzie');
d、 讲()Mitzie barks.
目前这是正确的行为(2020年10月)
当你设定
class A {
name
}
这声明了一个类字段。它还不是一个标准,它是。它可能会改变,但不会有太大的改变。阶段3是候选阶段,可能包括精加工
无论如何,根据提案的当前规范,您看到的是正确的。任何不带初始值设定项的类字段都设置为未定义
。这是因为在B
中有另一个名为name
的类字段,而没有初始化器。父构造函数中发生的赋值将被覆盖
:
没有初始值设定项的字段设置为undefined
无论是否存在初始值设定项,公共和私有字段声明都会在实例中创建字段。如果没有初始值设定项,则该字段设置为undefined
。这与某些transpiler实现有所不同,后者只会完全忽略没有初始值设定项的字段声明
例如,在下面的示例中,newd
将导致对象的y
属性为undefined
,而不是1
C类{
y=1;
}
D类扩展了C类{
Y
}
将没有初始值设定项的字段设置为undefined
,而不是删除它们的语义是,字段声明提供了一个可靠的基础,以确保创建的对象上存在属性。这有助于程序员将对象保持在相同的一般状态,这可以使其易于推理,有时在实现中更易于优化
是的,我本不想两次宣布我的名字,但我有一个bug。你说BabelJS/es2015没有问题?这是否意味着我没有使用它们?我正在使用许多es6功能,如
=>
和导入
。我很确定我也在用巴贝尔。我正在运行react应用程序并使用webpack。@Sam我无法察觉或回答环境问题,但选中特定复选框后,您的代码运行良好。所以,是的,巴贝尔可能没有加载,但从y端到判断,这是完全不确定的。在任何情况下,您都可以跳过name
的第二个声明。这也是MDN示例的原因。重写给定的默认值时,在子类中重新声明变量是有意义的。例如,父类中的name='John'
可以是子类中的name='Peter'
。我在B
的构造函数中调用A
的构造函数。构造函数完成执行后,name
的此字段是否已创建并初始化为undefined
?因为否则我会期望name
被初始化为undefined
,但是A
的构造函数会运行并覆盖它value@Sam是的,很明显,这个决定是为了确保没有初始值设定项的类字段总是未定义。因此,在B
中调用
super()`inB
将初始化this.name
inA
,但一旦B
,属性将被擦除回未定义的
。似乎在没有初始值设定项的情况下声明类字段的行为就好像在调用super()
之后有一个name=undefined
。我不确定我是否同意这个决定,但在隔离可能影响对象的更改方面有一些逻辑。如果A
没有名称
,但后来更改为对其进行初始化,则可能会更改B
的行为。