Private members in ES6

David White
Mar 25, 2016 · 2 min read

I’ve recently started to see a trend of methods prefixed with the underscore character in one of our projects at Sky. This is good in the sense that as our application is growing, and the number of methods we expose in our classes grows with it, the developers are considering what the public interfaces to these classes look like and finding a common pattern to distinguish the private interfaces.

However we’ve been able to hide away private methods and properties in JavaScript for a long time and prefixing those methods with an underscore, as some popular JS libraries and frameworks do ultimately ends in somebody using them where they shouldn’t.

With the new JavaScript class syntax we gain a slightly cleaner, more explicit in it’s intent syntax, we’ve actually been able to, and building private methods into Objects for some time now. I know many of the applications I wrote in ES5 used something along the lines of the “Immediately-Invoked Function Expression” or IIFE for short.

Working with ES6

This works very nicely as a pattern as the IIFE nicely encapsulates any of our methods that aren’t defined on the Service object. We could do the same thing using ES6, however if you’re already using ES6 then it’s likely you’re using Babel to transpile into ES5. We could accomplish the same above like so.

In this example we again will get a `privateMethod` is not a function if we try to call it, however I found that I needed to wrap my private method inside an object, otherwise Babel picked up during the transpilation process that the `this` within the `console.log function was undefined and changed this to undefined in the transpiled code.

Working with Symbols

A lesser known solution however is to use the new Symbol object.

A symbol is a unique and immutable data type and may be used as an identifier for object properties. The symbol object is an implicit object wrapper for the symbol primitive data type.

We can re-write the above code as follows using the Symbol object.

In the above code we define a symbol and assign it to a private constant. We can then both define the private method and call the private method using the square brackets syntax and passing in our Symbol as the name.

As symbols are unique, if we attempt to pass in a new symbol with the same string we will get an error as symbols are unique.

Wrapping up

My preferred solution for private members within JavaScript classes is to use Symbols. The syntax is less verbose and cleaner than in both previous examples as we don’t need to change the lexical scoping of this using the call method.

Unfortunately however there is still not support for Symbols within Internet Explorer, however if you’re already using a transpiler such as Babel then it’s likely you’re also using CoreJS polyfill.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store