Why would Bocoup, a company whose charge is to “move the open web forward,” be
publishing an article on something so nefarious-sounding as “information
hiding”? An article titled “Free Love & Information in JavaScript” would seem
much more apt for this blog. Trust me: if information hiding were an inherently
immoral practice, I wouldn’t know anything about it. I probably would have
spent most of high school trying to convince my peers that I was actually way
information hiding (despite being afraid of it).

In terms of programming, “information hiding” refers to the practice of
concealing implementation details that are unfit for the consumers of the code.
(As per usual, Wikipedia offers a nice
.) This prompts the
question: what do we mean by “consumers”?

  • If you’re working on a library, the “consumers” would be the developers using
    your library in their application logic. In those cases, you would want to
    “hide” methods that aren’t part of the API but that you wrote for internal
    use (for example, you might want to DRY out your

    by sharing code between them).
  • If you’re writing an application, “consumers” might refer to other developers
    on the project who use your module. As before, you wouldn’t want consumers to
    rely on details that you intended to change later on.
  • Since the browser is such an open execution environment, “consumers” could
    also refer to end users of the front-end application you are writing. Here,
    you might not want users to open up the JavaScript console and start
    tinkering with sensitive data and methods.

Whatever your particular perspective, I hope you can see how information hiding
can be a useful practice when it comes to structuring code. Just like smoking,
dancing, and attending the prom, it isn’t scary and it doesn’t have to end with
you sobbing in your mother’s arms. If you’re with me on that, it’s time to take
a look at how we might accomplish this in JavaScript.

Implementation Details

Like with most things JavaScript, web developers have a variety of options when
it comes to hiding implementation details. Here, I’d like to talk about five
distinct approaches: informal naming, per-instance closures, per-class
closures, obscurity, and symbols. For each approach, I’ll include a code
example for a simple Player class that implements:

  • private state for coins and lives
  • a private cashIn method
  • a public addCoin method

In all cases, the usage of the API will remain the same:

// Instantiate a player
var player = new Player();

// Award the player with two coins:

Informal Naming

A common convention among JavaScript developers is to simply prefix the names
of “private” data and functions with an underscore (_) character. Many open-
source JavaScript libraries follow this practice including
jQuery, Backbone.js,
Ember.js, and Knockout.js.
Because of this adoption, the practice serves as a reliable signal to consumers
that, “hey, don’t use this–I might change it later”. Here’s how it’s done:

function Player() {
  this._lifeCount = 3;
  this._coinCount = 0;

// The underscore in front of `_cashIn` tells consumers that this method is not
// intended for public use.
Player.prototype._cashIn = function() {
  this._lifeCount += Math.floor(this._coinCount / 100);
  this._coinCount %= 100;

Player.prototype.addCoin = function() {
  if (this._coinCount > 99) {

Of course, simply prefixing a method name with an underscore doesn’t stop
anyone from using it. This means that if you are interested in preventing
consumers from monkeying around with your application or SDK (maybe cheating at
a game or gaining unauthorized access), you’ll need to keep reading.

Per-instance closures

The “closure” in JavaScript can be a tricky beast, especially for developers
just getting started with the language. Basically, a closure is created
whenever a long-lived function holds a reference to (or “closes around”) a
short-lived function. If we define implementation details within the scope of
the constructor function, then public methods can “close” around them. This is
starting to feel a bit academic, so let’s return to the running example:

function Player() {
  var lifeCount = 3;
  var coinCount = 0;

  // When defined this way, `cashIn` will not be available outside of the
  // constructor.
  function cashIn() {
    lifeCount += Math.floor(coinCount / 100);
    coinCount %= 100;

  // We'll declare `addCoin` as an instance method by attaching it to `this`.
  this.addCoin = function() {
    if (coinCount > 99) {

Here, you can see that cashIn cannot be accessed outside of the Player
constructor. By closing over that function, however, the addCoin function can
use it. We attach the addCoin method to the instance itself because, as a
public API, we want this to be accessible to the consumer.

This approach suffers from two problems. The first relates to performance.
Thanks to the concept of “prototypal inheritance”, instance methods in
JavaScript are shared by all instances (classically-trained programmers may
recognize this as the “flyweight pattern” described by the “Gang of
This technique of information hiding eschews the performance benefits of code
sharing–each instance defines a unique copy of the addCoin and cashIn

Secondly, structuring code in this way does not scale particularly well. Any
Player method that needs to access the private API must be declared within
the constructor. This requirement will encourage growth of the constructor
function, making it more and more difficult to read and maintain.

Per-class closures

Instead of using the constructor as a closure for private methods, we could
declare private methods statically and then close around the constructor and
methods with an

var Player = (function() {

function Player() {
  this.lifeCount = 2;
  this.coinCount = 0;

// The private `cashIn` function is not accessible outside the IIFE's scope
function cashIn() {
  this.lifeCount += Math.floor(this.coinCount / 100);
  this.coinCount %= 100;

Player.prototype.addCoin = function() {
  if (this.coinCount > 99) {
    // We use "call invocation" to make sure the context of the `cashIn`
    // function is set to this instance of `Player`

// We need to explicitly "export" the `Player` class so that it is available
// outside the scope of the IIFE
return Player;


This approach successfully hides private methods, and those methods are
shared by all Player instances. But slow down there, this approach isn’t
perfect, either. You probably noticed that the instance variables lifeCount
and coinCount are exposed for all the world to see. This “per-instance
closure” approach only works for private methods.* So really, this approach is
too niche to be generally useful.


Let’s take a harder look at the “informal” approach we first considered. That
method was nice because it was memory-efficient and maintainable and because
it supported both instance methods and instance data. If we could find a way
to make those underscore-prefixed attributes truly private, we might have a
real solution on our hands…

It turns out, we can! Sort of! Instead of hard-coding the private attributes
with human-readable strings (i.e. "_addCoin" or "_lives"), we can name them
with dynamic randomly-generated strings. Then, we can keep a lookup table to
translate human-readable names to their randomly-generated counterparts (and
hide that inside a closure).

Not sure what I’m talking about? Neither am I, at this point. Let’s return to
the example for some clarity:

// We'll use an IIFE again so that our key isn't globally available
var Player = (function() {

// This is our map. Each time this code executes, the values of this object
// will be unique.
var KEY = {
  coinCount: Math.random(),
  lifeCount: Math.random(),
  cashIn: Math.random()

function Player() {
  this[KEY.lifeCount] = 3;
  this[KEY.coinCount] = 0;

Player.prototype.addCoin = function() {
  if (this[KEY.coinCount] > 99) {

Player.prototype[KEY.cashIn] = function() {
  this[KEY.lifeCount] += Math.floor(this[P.coinCount] / 100);
  this[KEY.coinCount] %= 100;

return Player;


In this example, instead of using “dot notation” to dereference the Person
instance with a simple string (as in this.lifeCount), we’re using the KEY
lookup table to retrieve the obscured name** (as in KEY.lifeCount), and
using that name to dereference the instance (as in this[KEY.lifeCount).
Notice how all this does not change the public API: person.addCoin() still
works as intended.

This solution is perfect, isn’t it?! Actually, it’s a nightmare. First of all,
who wants to write code like this? I don’t.

Second of all, we’re not so much hiding the information as we are obscuring it
(you might say we’re hiding it in plain sight). If you were to inspect a
Person instance in your browser’s JavaScript Console, you would see that it
defined two numeric attributes and one Function attribute (albeit with crazy
names like 0.5115215787664056). While this makes it very difficult for a
consumer to accidentally depend on these details (they change every time you
refresh the page), any dedicated adversary could probe at them enough to
reverse engineer our KEY lookup table. We could frustrate these efforts by
making the private properties non-enumerable with
but that will only work in browsers that implement ECMAScript

So while this will look great on our Wall of JavaScript Oddities, it probably
has no place in production.


For our last attempt to tackle this problem, we’ll be looking at functionality
that doesn’t exist today. ECMAScript
(sometimes referred
to as “ES6” or by its code name, “Harmony”) is the next version of the
JavaScript language specification. It includes a lot of exciting new features,
but for the purposes of this post, we’ll be focusing on Symbols. (If you’d like
to learn more about ES6, you should watch our very own Rick
‘s presentation,
“ECMAScript 6: My Favorite

One word of warning: ES6 is not a finalized standard. Symbols are still being
discussed, which means that the precise syntax discussed here may change over
time. (It also means that you can participate in its definition–head on over
to the es-discuss mailing list
to get involved.)

That said, lets take a look at what Symbols are (conceptually), and why they
might be useful in our goal to hide information. As you probably know, in
today’s JavaScript, any value you specify as a key to an object is
automatically coerced into a String. For example:

var myObject = {};
var objectKey = {};
// When we attempt to use an object as a key...
myObject[ objectKey ] = 4;

// It is coerced to a string, meaning the value is actually stored with the key
// '[object Object]' (the value returned by `Object.toString()`)
myObject['[object Object]'] === 4;

// This means that even though we might want to use a different object as a
// unique key for a different value...
myObject[ { a: 23 } ] = 6;

// ...the same attribute will be modified, since by default, all object share
// the same generic String representation.
myObject['[object Object]'] === 6;

Symbols are objects specifically designed to avoid this behavior: when used as
keys to an object, they will not be coerced to Strings.

If we encapsulate the Symbols, then we can use them to define “private”
attributes of publicly-accessible objects–true information hiding in
JavaScript! Here’s how it might be done:

var Player = (function() {

// Define the Symbols that we'll use as keys for the private API
var lifeCount = Symbol(),
  coinCount = Symbol(),
  cashIn = Symbol();

function Player() {
  // When used to dereference the `Player` instance, Symbols will not be
  // converted to String values
  this[lifeCount] = 3;
  this[coinCount] = 0;

Player.prototype.addCoin = function() {
  if (this[coinCount] > 99) {

Player.prototype[cashIn] = function() {
  this[lifeCount] += Math.floor(this[coinCount] / 100);
  this[coinCount] %= 100;

return Player;


This should look familiar–it’s basically identical to the “Obscurity” approach
described previously (with Symbols replacing random numbers). Given the
similarities, it’s reasonable to wonder if it’s actually an improvement at all.
Because Symbols are unique objects in memory, they cannot be “forged” or
“guessed” in the same way that string values can. We rejected the “Obscurity”
approach because of this very weakness in String keys, so Symbols address the
only flaw with that approach.

But wait! There’s more! The square brackets all over the above example can be
kind of a drag to write. Lucky for us, an alternative syntax for working with
Symbols in the context of ES6 modules makes them even more readable.

As I’ve already pointed out, ECMAScript 6 is still being specified. Different
features have reached different levels of consensus. There’s no telling how
“at-names” and the private keyword might change change as ES6 matures. What
I’m about to show you is volatile–my brow was sweating and my hands were
shaking as I painstakingly typed it all out:

var Player = (function() {

// Define private Symbols using the "at-name" syntax
private @lifeCount, @coinCount, @cashIn;

function Player() {
  // Use the Symbol with dot notation to dereference the Player instance!
  this.@lifeCount = 3;
  this.@coinCount = 0;

Player.prototype.addCoin = function() {
  if (this.@coinCount > 99) {

Player.prototype.@cashIn = function() {
  this.@lifeCount += Math.floor(this.@coinCount / 100);
  this.@coinCount %= 100;

return Player;


This code just feels so much cleaner without all those square brackets, doesn’t
it? Eagle-eyed readers will note that this code looks eerily similar to the
code in the first “Informal Naming” approach. Really, the only differences are
the initial declaration of symbols, and a replacement of the underscore
character (_) with the “at” sign (@). I give a lot of credit to the
language designers for this fact. This syntax recognizes the informal
convention already in use today and “makes it real” through a trivial

I know I said that ECMAScript 6 doesn’t exist today, but we don’t have to let
that stop us from playing with these ideas. Just like Dr. Emmit Brown, we can
experiment with these visions of the future to create something remarkable.
The Continuum project gives us a glimpse
as to what it might be like to write JavaScript with next-generation features
including, you guessed it, Symbols.


It’s been a long road, but we finally found a complete solution for information
hiding in JavaScript… or did we? After all, ECMASript 6 still isn’t complete,
let alone implemented in enough browsers for general use. Where does that leave
us, the modern-day developers yearning for private state?

For my part, I’ll be sticking to the informal naming convention for the
foreseeable future. No other approach is as recognizable, maintainable, or
powerful as simply denoting private APIs with an underscore.

We can’t forget that convention alone will not stop malicious adversaries, but
that problem is much bigger than information hiding. At the end of the day,
the browser remains an inherently insecure execution
; no
amount of JavaScript trickery can fix that. If you are writing client-side code
that needs to be trusted, my advice is to off-load sensitive operations to a
secure server.

This may be a disappointing conclusion to our investigation, but sometimes
simplicity trumps all other requirements.

* – In environments that implement WeakMaps from ECMAScript 6, you could
build a WeakMap that associated Player instances with private data, but as
we’ll see, ES6 promises a far more convenient primitive for hiding
** – As avid readers of this blog know, Math.random() isn’t sufficiently
random for cryptographic
, but it should do for
our purposes.