繁体   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