Sat Jan 21 2017
Paul Shan
Since the world moved from ES5 to ES6, huge syntactical (not only syntactical) changes took place to make out JavaScript codebase more beautiful. Though every other syntaxes have been improved, but one thing which is troubling the developers is, how to declare the private variables inside a class. But unfortunately there is no dedicated syntax to do that in ES6.
No! There’s no dedicated syntax to declare a private in ES6. But there’s a proposal submitted.
class MyClass{
#private1;
#private2;
getPrivate1(){
return this.private1;
}
}
The above syntax is a proposal submitted to TC39. This is yet to be approved and will certainly not be available in near future, but we can hope, in some future versions of ES, we will get this.
You can create modules and everything inside that will be private until and unless you make it public using exports
.
let private1 = new WeakMap();
let private2 = new WeakMap();
class MyClas{
constructor(){
this.setPrivate1("something");
private2.set(this, "something else");
}
getPrivate1(){
return private1.get(this);//"something"
}
getPrivate2(){
return private2.get(this);//"something else"
}
setPrivate1(val){
private1.set(this, val);
}
}
module.exports = MyClass;
Why didn’t we declare a variable private1 and assign it the value it needs? The reason is, the variable private1 is a single variable which will be shared across all the instances of MyClass
. So if any instance change the private1, the same will be reflected to the other instance.
The difference between Map and WeakMap will automatically delete the value if the key object is ready to be garbaged. Whereas in case of Map, it will keep a reference of the key object forever. Thus memory leak will be caused.
There are few other ways too to declare privates with their own pros and cons. Two of them are described below.
Since ages people are using underscores in the name of the private variables. Depending on that convention and having a trust on your fellow developers you can use this method.
This doesn’t ensure the safety of your data as if anyone wants, he can use or even change that data. In case you are creating a library, this method is highly unrecommended.
class MyClass{
constructor(){
this._private1 = "something";
this.public = "something else";
}
}
Using Object.assign you can use private variables which will ensure the safety of your data too. But the issue with that is, the methods which are going to read/write that private variable, can not be prototypal methods. Along with the private variables, those methods also have to be written inside the constructor. This, not only makes it difficult to read for another developer, but also is an inefficient way to declare functions; as those functions will be repeated (not shared) in every instance of that class.
class MyClass{
constructor(){
var private1 = "something";
Object.assign(this, {
getPrivate(){
return private1;
},
setPrivate(val){
private1 = val;
}
});
}
anotherMethod(){
console.log(private1); //ERROR
}
}
Some people may recommend using ES6 Symbols to create private variables. Months ago that approach was effective, but ES6 has changed it drafts and now Symbol keys are accessible from outside of an object. So there’s no meaning to follow that way. However the best practice is to divide your program in modules and use the first method I showed to declare private. Using this you ensure the safety, all methods of that class will be able to access that data. The only drawback I see is it given you a hack type of feeling as it’s not as the private is not as much related to the class as the things in naming convention way are.
SHARE THIS ARTICLE
Thu Mar 10 2016
OAuth authentications are pretty popular now a days and another thing which is popular is JavaScript. This article shows how to plugin google’s oAuth api for authentication in your own node application.Sat Mar 01 2014
This is a continuation of my CSS3 loader snippet collection series. I've provided spinning css3 animation loader in the part 1 of this series and here in part 2, I'm providing various square type loading