[英]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 name
和set 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.