Cover image by Christiaan Colen on Flickr
As you may noticed, JavaScript got real classes with it's ES2015 update, but many people still want better support for classical OOP. The way to define instance fields is rather cumbersome and there is no way to make a field private.
All this will change with this new proposal: Class Fields
Why
Defining classes is rather simple in JavaScript.
class A {}
But giving the instance of that class fields is a bit strange.
class A {
constructor() {
this.field = 123;
}
}
const a = new A();
console.log(a.field);
Also, this field is now public, so everyone can access and modify it.
The current convention for this is to prepend a field with _
to mark it as private, but this is more of a hack than a solution.
How
This new proposal allows to define real fields without the help of the constructor.
class A {
field = 123;
}
const a = new A();
console.log(a.field);
The fields can even access each other.
class A {
x = 10;
y = 10 + this.x;
}
const a = new A();
console.log(a.y);
This works, because the whole class desugars to something like this.
var A = function A() {
this.x = 10;
this.y = 10 + this.x;
};
Also, this feature can be used to define methods, that always have the right this
.
class A {
x = 10;
m = () => console.log(this.x);
}
const a = new A();
const callback = a.m;
setTimeout(callback, 100); // 10
This desugars to something like this:
var A = function A() {
var _this = this;
this.x = 10;
this.m = function () {
return console.log(_this.x);
};
};
There is even the idea to allow private fields:
class A {
#a = 10;
m = () => this.#a;
}
const a = new A();
console.log(a.a);
console.log(a.m());
Sadly this doesn't seem to be implemented, not even in Babel.
Conclusion
More and more classical OOP features find its way into JavaScript. While I'm not the biggest fan of OOP in general and found the prototype based approach more flexible, I think this will make JavaScript more accessible for developers coming from those classical OOP languages.