All module patterns that need to have truly private data must inherently use an IIFE to maintain their own private scope. Even the object literal module pattern uses this. See a comparison of some module patterns,
You can store pseudo-private data in a couple of ways with an object literal:
By convention, properties that start with an _
underscore are understood to be off-limits to the rest of the world.
{
_privateBar : 1
publicFoo : 4,
}
Alternatively, you can use symbols.
const privateBar = Symbol('private');
myModule[privateBar] = 1;
myModule.publicFoo = 4;
Using the latter, only a reference to the privateBar
symbol object can get you the value of 1
from myModule
. And no, you can't get it with myModule[Symbol('private')]
, because symbols are unique and Symbol('private') === Symbol('private')
is false
.
Unfortunately, they decided to add Object.getOwnPropertySymbols(), so an object's symbols are not truly private and are not suitable for protecting data from malicious activity.
However, in practice, most operations you perform (for of
loops, etc.) will not touch symbols. And therefor it is an excellent replacement for the underscore _
convention. But sometimes there are even better ways, such as using a WeakMap.
Using ES6 we can actually avoid the slight overhead of an IIFE thanks to lexical scoping.
const myModule = {};
{
const privateBar = 1;
myModule.publicFoo = 4;
}