How to define private variables in EcmaScript 2015 (ES6)

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.

New proposal (not implemented yet)

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.

Best way to declare private

You can create modules and everything inside that will be private until and unless you make it public using exports.

let private1 = “something”; Why not this way?

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.

Why not Map instead of WeakMap?

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.

Other ways to declare private

There are few other ways too to declare privates with their own pros and cons. Two of them are described below.

Naming conventions

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.

Object.assign

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.

Conclusion

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.

About This Author

Hello! I am Paul Shan, a JavaScript Expert, Full Stack and DevOps Engineer cum Consultant based out of Bengaluru, India.

  • Philip Taylor

    “ES6 has changed it drafts and now Symbol keys are accessible from outside of an object.”. What are you referring to here? I assume its ‘Object.getOwnPropertySymbols()’ which seems to spoil the whole point of Symbols.

    • Paul Shan

      Yes. Object.getOwnSymbols() & Object.getOwnPropertySymbols().
      However, I won’t say it actually spoiled anything. Symbols were not created to keep private. Rather they are used to prevent override; which they are doing perfectly well.

    • Philip Taylor

      You mean properties in subclasses overriding properties in super classes? I haven’t seen that discussed yet.
      What I mean by spoiling, is that if they didn’t include that method we would have properly private members today (a badly needed feature). Instead we have to wait for some future spec or use WeakMaps etc..
      Overrides don’t seem so critical to me.

    • Paul Shan

      No, I didn’t mean override in inheritance.
      What I meant was; suppose you are using an animation library to animate a div in your DOM. That library is setting a property currentPosition in that div object. You are also using another library to display stock market things on that div and that library also sets a currentPosition property on that div.
      Now your program will break cause both this libraries will be overriding the same property in div object and won’t be able to work.
      This is a scenario for Symbols. Both this libraries could be using Symbol(‘currentPosition’) and as symbols are completely unique, they won’t override each others value and both the libraries will work smoothly.
      Yes, working with WeakMap adds extra complexity. The community understand that and thus proposed for a proper private variable descriptor #. It’s currently in stage 2 and if all goes well, you will soon be able to use it in your programs. Check it here http://ecmascript.in/proposals?q=private