Node.js 12 supports private class fields denoted by # out-of-the-box, without flags or transpilers.
For example, this works with 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
Let's say I want to construct my Foo instance not with 1 property, but with 20 – I would have to duplicate the assignment statement in the constructor and the getter function 20 times, which makes for a lot of boilerplate code.
If I didn't use private fields but regular class fields, this would not be hard to avoid:
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
However, with private class fields, it does not work:
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 :-(
I've also tried assigning a value to the private class field in the constructor using Reflect.set, to no avail:
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 :-(
Can I set a private class field using a variable as identifier? If yes, how?