簡體   English   中英

未聲明類字段時出現太多遞歸錯誤

[英]Too much recursion error when a classfield is not declared

如果我們像這樣聲明一個 class:

class client{
  constructor(name){
    this.name = name
  }

  get name()
  {
    return this.name ; 
  }
  set name(val)
  {
    this.name = val ;
  }
}

實例化它會給出一個錯誤(太多的遞歸)並且這是正常的,因為 setter 會調用自己。

 class client{ constructor(name){ this.name = name } get name() { return this.name; } set name(val) { this.name = val; } } let cl = new client();

但是當我將“名稱”聲明為 class 字段時,我沒有收到該錯誤,我不明白為什么。

 class client{ name = null; constructor(name){ this.name = name } get name() { return this.name; } set name(val) { this.name = val; } } let p = new client(); console.log(p);

TL;DR您不能在同一個 object 上同時擁有同名的數據屬性和訪問器屬性,如果您在 object 上擁有數據屬性,則不會使用其原型上具有相同名稱的任何屬性(除非你明確地這樣做)。 name class 字段定義在正在構造的 object 上創建了自己的數據屬性。


在第一種情況下(我想你知道), name setter 中的this.name再次調用name setter,遞歸直到你用完堆棧。 (吸氣劑也一樣,如果你用過的話。)

那么,當您在那里有那個name字段定義時,有什么不同呢?

定義 class 字段的方式,該name定義在正在創建的實例上創建了一個自己的屬性,就好像您在構造函數的開頭有這段代碼(如果這是一個子類,就在super調用之后):

constructor(name) {
    // Definition of `name` field:
    Object.defineProperty(this, "name", {
        value: undefined,
        writable: true,
        configurable: true,
        enumerable: true,
    });
    // Remainder of constructor code:
    this.name = name;
}

因為它是一個own屬性,所以this.name解析為該數據屬性,而不是get nameset name訪問器定義創建的原型上的訪問器屬性。 所以p的原型上的那些訪問器從未被使用過。

如果您查看第二個示例中屬性的定義,您會發現:

 class client { name = null; constructor(name){ this.name = name; } get name() { return this.name; } set name(val) { this.name = val; } } let p = new client(); console.log(p); console.log(Object.getOwnPropertyDescriptor(p, "name"));

如果你想擁有 accessor 屬性,你可以使用一個私有字段,這是一個很新但在現代環境中受支持的字段:

 class Client { #name = null; constructor(name) { this.#name = name; } get name() { return this.#name; } set name(val) { this.#name = val; } } let p = new Client("Joe"); console.log(p.name); console.log(Object.getOwnPropertyDescriptor(p, "name")); // undefined console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(p), "name")); // accessor
 .as-console-wrapper { max-height: 100%;important; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM