2

This code works:

class Test {
  #field

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

But if I want to calculate field name I have to use square brackets but it doesn't work:

class Test {
  #field;

  get field() {
    return this['#field'];
  }
}

Is there any way to get private field with calculated name?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • What do you mean by "calculated name"? Your example is using a static string. – Taplar Sep 01 '20 at 19:23
  • It's probable that this is an abstraction of the actual code that demonstrates the issue. I'm wondering if the shim that OP is using has documented this behavior. It looks like this is a [proposal](https://github.com/tc39/proposal-class-fields) with multiple implementations. What environment are you using? – Charlie Bamford Sep 01 '20 at 19:25
  • 1
    The `#` for private class member is still experimental and shouldn't be used for production systems. (Firefox doesn't support it) Also, it's not intended to be used in `[]`. If you want to have dynamic fields, you could do `this.#fields['myfield'];` where `#fields` was declared like `#fields = {field1: 1, field2: "a"};`. – Dominique Fortin Sep 01 '20 at 19:34
  • 1
    Quote from the [proposal](https://github.com/tc39/proposal-class-fields#private-syntax): "There are no private computed property names: `#foo` is a private identifier, and `#[foo]` is a syntax error." – CherryDT Sep 01 '20 at 19:41

2 Answers2

2

It looks like it is a problem to hand over a string which has a special meaning.

If really necessary, you evaluate a string.

class Test {
    #field = 'foo';

    get field() {
        return eval('this.' +'#field');
    }
}

console.log(new Test().field)
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

This is not possible. From the proposal:

There are no private computed property names: #foo is a private identifier, and #[foo] is a syntax error.

and its FAQ:

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

  1. This would complicate property access semantics.

  2. Dynamic access to private fields is contrary to the notion of 'private'. E.g. this is concerning:

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

But doesn't giving this.#x and this['#x'] different semantics break an invariant of current syntax?

Not exactly, but it is a concern. this.#x has never previously been legal syntax, so from one point of view there can be no invariant regarding it.

On the other hand, it might be surprising that they differ, and this is a downside of the current proposal.

See also this issue.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375