亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Javascript:為什么在子類中聲明一個屬性會覆蓋超類中的相同屬性為空

Javascript:為什么在子類中聲明一個屬性會覆蓋超類中的相同屬性為空

慕婉清6462132 2023-05-11 09:51:44
我的問題與理解類如何為屬性賦值以及如何在 Javascript 中實例化對象有關。我想更多地了解這個過程是如何工作的。如果我創建兩個類,其中第二個繼承自第一個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 變量分配為傳遞給它的值?
查看完整描述

2 回答

?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

目前(2020 年 10 月)這是正確的行為。

當你設置

class?A?{
????name
}

這聲明了一個類字段。這還不是一個標準,它是第 4 階段的提案。它可能會改變,但不會太大。第 3 階段是候選階段,可能包括完成改進。

無論如何,根據提案的當前規范,您所看到的是正確的。任何沒有初始化器的類字段都設置為undefined.?發生這種情況是因為您在沒有初始化程序的情況下調用了另一個類name字段B。父構造函數中發生的賦值將被覆蓋。

以下是討論此行為的提案的相關部分:

沒有初始值設定項的字段設置為undefined

公共和私有字段聲明都會在實例中創建一個字段,無論是否存在初始化程序。如果沒有初始值設定項,則該字段設置為undefined.?這與某些轉譯器實現有些不同,后者會完全忽略沒有初始化器的字段聲明。

例如,在以下示例中,將生成屬性為而非 的new D對象。yundefined1

class?C?{
??y?=?1;?
}?
class?D?extends?C?{
??y;?
}

在沒有初始化器的情況下設置字段而不是擦除它們的語義undefined是字段聲明提供可靠的基礎以確保屬性存在于創建的對象上。這有助于程序員將對象保持在相同的一般狀態,這可以使推理變得容易,有時在實現中更可優化。


查看完整回答
反對 回復 2023-05-11
?
縹緲止盈

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 / ES2015SO 中代碼段配置中的復選框,則您的代碼不會出現任何問題。

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);


查看完整回答
反對 回復 2023-05-11
  • 2 回答
  • 0 關注
  • 199 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號