【问题标题】:js dynamically access private fields (properties/members)js动态访问私有字段(属性/成员)
【发布时间】:2020-04-13 21:44:44
【问题描述】:

我正在试用新的class private member feature ????但是,我很快遇到了一个问题:如何动态访问它们?

我希望它遵循任何一个预先存在的语法

constructor(prop, val) {
  this[`#${prop}`] = val; // undefined
}

constructor(prop, val) {
  this.#[prop] = val; // syntax error
}

但是,以上两种方法都失败了。

【问题讨论】:

  • 您是否尝试过先创建属性并进行设置?
  • 是的,我实际将它们预先声明为空对象。如果我在构造函数中手动枚举它们并将它们设置为 val,那么效果很好(尽管非常乏味和脆弱),但是包罗万象的 get 和 set 有同样的问题——这违背了它们的目的,所以必须有一种动态执行此操作的方法(否则 JS 作者会做出巨大的疏忽)。
  • this[`#${prop}`] 只会设置一个普通属性,因为无法判断它是私有的还是包含# 的常规合法属性名称。至于tc39 proposal 中的#[prop],据说是语法错误,因为它们没有计算出的道具名称。所以当前阶段可能无法进行动态访问
  • 呃,我希望这不会是一个禁止性/排他性的限制。 MDN 文档表明 # 只是名称的一部分,因此基于此,我希望串联能够正常工作????
  • @jacob 检查adriancg 答案

标签: javascript private private-members class-fields


【解决方案1】:

另一种选择是为您想要动态访问的密钥创建一个私有对象:

class privateTest {
  #pvt = {}

  constructor(privateKey, privateVal) {
    this.#pvt[privateKey] = privateVal;
  }

  getPrivate(privateKey) {
    return this.#pvt[privateKey];
  }

}

const test = new privateTest('hello', 'world');
console.log(test.getPrivate('hello')) // world

【讨论】:

    【解决方案2】:

    我认为您不能动态访问私有字段。 proposal 说:

    没有私有计算属性名称:#foo 是私有标识符,#[foo] 是语法错误。

    【讨论】:

      【解决方案3】:

      来自关于私有财产提案的常见问题解答:

      对私有字段的动态访问与“私有”的概念相反。

      https://github.com/tc39/proposal-private-fields/blob/master/FAQ.md#why-doesnt-thisx-access-the-private-field-named-x-given-that-thisx-does

      缺乏对私有字段的动态访问是设计使然。

      【讨论】:

      • 虽然在 OP 的情况下(以及我为什么要搜索这个),但他希望在私有范围内动态访问私有字段。一切都保持私密。对我来说,我有一堆保存私有回调函数的变量,并且希望有一个我可以动态访问的方法名称的字符串数组。
      【解决方案4】:

      如果您真的想这样做。

      eval(`this.#${propertyName}`)
      

      但这只是打开了一个非常丑陋的蠕虫罐。

      【讨论】:

      • 因此,为了实现这一目标,您必须转向黑暗面。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多