簡體   English   中英

我可以使用變量作為標識符來設置私有 class 字段嗎? 如何?

[英]Can I set a private class field using a variable as identifier? How?

Node.js 12 支持由# out-of-the-box 表示的私有 class 字段,沒有標志或轉譯器。

例如,這適用於 Node.js 12:

class Foo {
  #bar = 1;

  constructor({ bar }) {
    this.#bar = bar;
  }

  get bar() {
    return this.#bar;
  }
}

const foo = new Foo({ bar: 2 });

console.log(foo.bar); // 2

假設我想用 20 而不是 1 個屬性來構造我的 Foo 實例——我必須在構造函數和 getter function 中復制賦值語句 20 次,這會產生很多樣板代碼。

如果我不使用私有字段,而是使用常規 class 字段,這不難避免:

class Foo {
  bar = 1;

  constructor(properties) {
    Object.entries(properties).forEach(([name, value]) => (this[name] = value));
  }

  get bar() {
    return this.bar;
  }
}

const foo = new Foo({ bar: 2 });

console.log(foo.bar); // 2

但是,對於私有 class 字段,它不起作用:

class Foo {
  #bar = 1;

  constructor(properties) {
    Object.entries(properties).forEach(
      ([name, value]) => (this[`#${name}`] = value)
    );
  }

  get bar() {
    return this.#bar;
  }
}

const foo = new Foo({ bar: 2 });

console.log(foo.bar); // 1 :-(

我還嘗試使用 Reflect.set 為構造函數中的私有class字段分配一個值,但無濟於事:

class Foo {
  #bar = 1;

  constructor(properties) {
    Object.entries(properties).forEach(([name, value]) =>
      Reflect.set(this, `#${name}`, value)
    );
  }

  get bar() {
    return this.#bar;
  }
}

const foo = new Foo({ bar: 2 });

console.log(foo.bar); // 1 :-(

我可以使用變量作為標識符來設置私有 class 字段嗎? 如果是,如何?

不,這看起來不可能。 提案常見問題解答

為什么 this['#x'] 不訪問名為 #x 的私有字段,因為 this.#x 可以?

  1. 這會使屬性訪問語義復雜化。

  2. 對私有字段的動態訪問與“私有”的概念相反。 例如,這是關於:

 class Dict extends null { #data = something_secret; add(key, value) { this[key] = value; } get(key) { return this[key]; } } (new Dict).get('#data'); // returns something_secret

語法是這樣的,每個私有字段都必須在文字屬性名稱之前用#進行初始化和/或引用,僅此而已。 甚至不允許使用括號表示法。

擁有一個名為 x 的私有字段不能阻止有一個名為 x 的公共字段,因此訪問私有字段不能只是正常的查找。

You can't even reference a private field unless it's explicitly defined in the class body ( not a class function, but inside the class body directly):

 class Foo { // error is thrown because #abc must be defined in this section doSomething() { return this.#abc; } }

也就是說,沒有什么能阻止您創建一個私有屬性object ,所有這些屬性都在 object 上:

 class Foo { #privates = {}; constructor(properties) { Object.entries(properties).forEach( ([name, value]) => (this.#privates[name] = value) ); } get privates() { return this.#privates; } } const foo = new Foo({ bar: 2 }); console.log(foo.privates.bar);

暫無
暫無

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

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