【问题标题】:Choose private field at runtime在运行时选择私有字段
【发布时间】:2019-12-30 20:35:34
【问题描述】:

使用公共字段我可以这样做:

class Smth {
  a = 0
  b = 0

  constructor(value, isA) {
    this[isA ? 'a' : 'b'] = value
  }
  
  toString() {
    return `(${this.a}, ${this.b})`
  }
}

console.log(new Smth(1, true) + "")
console.log(new Smth(2, false) + "")

我可以为私有字段使用什么等价物?

我只看到eval 的解决方案:

class Smth {
  #a = 0
  #b = 0

  constructor(value, isA) {
    eval(`this.#${isA ? 'a' : 'b'} = value`)
  }
  
  toString() {
    return `(${this.#a}, ${this.#b})`
  }
}

console.log(new Smth(1, true) + "")
console.log(new Smth(2, false) + "")

或完全分支到if-else的解决方案:

class Smth {
  #a = 0
  #b = 0

  constructor(value, isA) {
    if (isA) {
      this.#a = value
    } else {
      this.#b = value
    }
  }
  
  toString() {
    return `(${this.#a}, ${this.#b})`
  }
}

console.log(new Smth(1, true) + "")
console.log(new Smth(2, false) + "")

这两种解决方案都不适合我。


如果没有这样的方法,我想知道为什么。

很明显 this['#x'] 完全是另一回事。但是有很多方法可以用其他语法表达所需的东西,例如:

this.#[true ? 'x' : 'y']
this[true ? #x : #y]
this.#[true ? #x : #y]
this.#(true ? ##x : ##y)

还有很多其他的。为什么不呢?

【问题讨论】:

标签: javascript private


【解决方案1】:

Source

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

Why doesn't this['#x'] access the private field named #x, given that this.#x does?

要解决这个问题,您需要使用 if/else 语句并以非动态方式设置每个语句:

class Smth {
  #a = 0
  #b = 0

  constructor(value, isA) {
    isA ? (this.#a = value) : (this.#b = value)
  }
  
  toString() {
    return `(${this.#a}, ${this.#b})`
  }
}

console.log(new Smth(1, true) + "")
console.log(new Smth(2, false) + "")

【讨论】:

  • 很明显this['#x'] 完全是另一回事。但是有很多方法可以用其他语法表达所需的东西,例如:this.#[true ? 'x' : 'y']this[true ? #x : #y]this.#[true ? #x : #y]this.#(true ? ##x : ##y) 等等。为什么不呢?
  • @Qwertiy 原因在于我分享的链接对私有字段的动态访问与“私有”的概念相反。
  • 在 C++ 中我可以写 (true ? this.x : this.y) = 0; 但不能在 js 中:(
猜你喜欢
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
  • 2012-09-11
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多