Lucas
Lucas

Reputation: 65

How to declare a true #private field with Symbol?

I try to declare private Symbol property in ES6+ class, below's approach are all wrong.

class MyClass {
  #[Symbol.for('my-symbol-prop1')] = 'my-symbol-prop1';  // SyntaxError
  [#Symbol.for('my-symbol-prop1')] = 'my-symbol-prop1';  // SyntaxError
}

My question: Is there any way to declare a true private Symbol property, just using hash notation like #myPrivateSymbolfield, don't using WeakMap or enclosure approach

Upvotes: 0

Views: 130

Answers (3)

Lucas
Lucas

Reputation: 65

I guess it's because Symbol is used to create unique identifiers to avoid attribute name conflicts in the future.
And true #private field is accessible only from within the class in which it is declared, also true #private field actually not a property to this(this in instanceMethod or staticMethod), as MDN page - Private properties says:

The privacy encapsulation of these class properties is enforced by JavaScript itself.

Thus you have no reason to use Symbol to declare private fileds, hash notation #privateField just wouldn't cause attribute name conflicts in the future, since you can't access #privateField out of the class where you declared it.

Upvotes: 0

mandy8055
mandy8055

Reputation: 6735

Currently in JavaScript, there isn't a direct way to create private Symbol properties using the private field syntax (#). The private fields feature and Symbol properties serve different purposes. Having said that, you can easily do a workaround for the same i.e. use a static private field to store the symbol. Something like below:

class MyClass {
  [Symbol.for('my-symbol-prop')] = 'symbol';
  
  // Private Symbol wokraround using private field
  static #privateSymbol = Symbol('privateSymbol Desc');
  
  constructor() {
    /* The Symbol itself can be accessed via the getter
    but the property using this Symbol is still private */

    this[MyClass.#privateSymbol] = 'private symbol value';
  }
  
  get privateSymbolValue() {
    return this[MyClass.#privateSymbol];
  }
}
// Usage
const myClass1 = new MyClass();
const myClass2 = new MyClass();
console.log(myClass1.privateSymbolValue);
console.log(myClass2.privateSymbolValue);

Upvotes: 0

Bergi
Bergi

Reputation: 665276

This is not possible. Symbol-keyed properties are just regular object properties (just with symbols instead of string names), not private fields. If you want a field with a private name, do not use symbols.

Upvotes: 0

Related Questions