DEV Community

loading...
Cover image for JavaScript Class Improvements

JavaScript Class Improvements

kayis profile image K ・2 min read

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 {}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

The fields can even access each other.

class A {
  x = 10;
  y = 10 + this.x;
}

const a = new A();

console.log(a.y); 
Enter fullscreen mode Exit fullscreen mode

This works, because the whole class desugars to something like this.

var A = function A() {
  this.x = 10;
  this.y = 10 + this.x;
};
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

This desugars to something like this:

var A = function A() {
  var _this = this;
  this.x = 10;
  this.m = function () {
    return console.log(_this.x);
  };
};
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (11)

pic
Editor guide
Collapse
mangekalpesh profile image
Kalpesh Mange

Some really new stuff I didn't know before! Thanks a heap! ES6 FTW!

Collapse
kayis profile image
K Author

Technically not even ES2018, but yes. :)

Collapse
mangekalpesh profile image
Kalpesh Mange

Dang! It's hard to keep updated with the numbering! :P

Thread Thread
kayis profile image
K Author

yes, every year another JS

Collapse
mortoray profile image
edA‑qa mort‑ora‑y

I'd really like to have a strict mode for fields as well: only declared fields exist. Right now typos can ruin everything, when you have this.itemList in the constructor and assign to this.itmeList elsewhere, then spend a half-day scratching you head wondering why some bits of the code don't work!

Collapse
kayis profile image
K Author

Guess that's what you get with dynamic typing :D

Collapse
renannobile profile image
Renan Lourençoni Nobile

Isn't "use strict" the solution for that kind of situation?

Collapse
kayis profile image
K Author

Sadly no.

TypeScript or Flow are the solution.

Collapse
hamzaop profile image
Hamza • Edited

Thanks for the article ! ,but I have a small remark regarding that javascript has now real classes,it's not true, javascript is always prototype-based, the class keyword is no more than syntactical sugar , because believing the language has real classes can lead to confusion in developement especially when comparing to other class-based languages.

Collapse
kayis profile image
K Author

This is true.

The prototype approach of JavaScript is more flexible than the stuff that other languages are doing. In fact, most people did implement their own class system on top of it, the ES2015 class syntax is just a standardization of these systems.

Collapse
tunna29 profile image
tunna29

helpful to me
but i have some problems

i dont understand this : var A = function A() {
var _this = this;
this.x = 10;
this.m = function () {
return console.log(_this.x);
};
};

we have a variable named A , so why do we need the name A for the function