Skip to content

Instantly share code, notes, and snippets.

@Rich-Harris
Last active December 18, 2015 17:09
Show Gist options
  • Save Rich-Harris/5816218 to your computer and use it in GitHub Desktop.
Save Rich-Harris/5816218 to your computer and use it in GitHub Desktop.
A solution to the problem posed by Mike Pennisi on http://weblog.bocoup.com/info-hiding-in-js/ - per-instance private variables and methods that don't forgo the benefits of prototypal inheritance or rely on obscurity (or ES6)
var Player = (function () {
var Player, generateGuid, maxCoins, secrets, get, set, cashIn;
maxCoins = 100;
// via http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
generateGuid = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r, v;
r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
};
secrets = {};
get = function ( player, property ) {
var data = secrets[ player.guid ];
return data[ property ];
};
set = function ( player, property, value ) {
var data = secrets[ player.guid ];
data[ property ] = value;
};
cashIn = function ( player ) {
var coinCount, lifeCount;
coinCount = get( player, 'coinCount' );
lifeCount = get( player, 'lifeCount' );
lifeCount += Math.floor( coinCount / maxCoins );
coinCount %= maxCoins;
set( player, 'coinCount', coinCount );
set( player, 'lifeCount', lifeCount );
};
Player = function () {
Object.defineProperty( this, 'guid', {
value: generateGuid()
});
secrets[ this.guid ] = {
coinCount: 0,
lifeCount: 3
};
};
Player.prototype = {
addCoin: function () {
coinCount = get( this, 'coinCount' );
set( this, 'coinCount', ++coinCount );
if ( coinCount >= maxCoins ) {
cashIn( this );
}
}
};
return Player;
}());
@Rich-Harris
Copy link
Author

As @lawnsea points out, this wasn't entirely foolproof - you can swap GUIDs between player instances. In all modern browsers you can use Object.defineProperty() to make the guid property read-only. Code updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment