Skip to content

Instantly share code, notes, and snippets.

@timdream
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timdream/379bdd1d26d807556bba to your computer and use it in GitHub Desktop.
Save timdream/379bdd1d26d807556bba to your computer and use it in GitHub Desktop.
Private method/property with WeakMap
'use strict';
/**
* Demonstration for creating private variable/method in JavaScript
* constrcutors, with WeakMap trick.
*
* The idea here is to create two WeakMaps to link a public instance and
* a private instance, and two shorthand query function to query between two.
*
* Both instances can therefore have their own methods respectively.
* An "apply()" apply trick is also demonstrated in privateMethod2() but
* it's too confusing thus not recommended.
* "pubThis" and "privThis" should be more understandable in this setup.
*
* Note that even though this is shown passing "window" as exporting object,
* it can surely be the module.exports in CommonJS environment.
* The point here is to have your own closure to encapsulate the WeakMaps.
*
* I expect, if anyone will ever use this setup, most of the methods will be
* in the PrivateClass and PublicClass will simply be a wrapper/pointers
* to the methods & properties. It would be easier to keep most of the lines
* pointing to the same "this".
*/
(function(exports) {
var publicPrivateInstanceMap = new WeakMap();
var _p = publicPrivateInstanceMap.get.bind(publicPrivateInstanceMap);
var privatePublicInstanceMap = new WeakMap();
var _rp = privatePublicInstanceMap.get.bind(privatePublicInstanceMap);
var PrivateClass = function() {
};
PrivateClass.prototype.linkWithPublicInstance = function(publicInstance) {
publicPrivateInstanceMap.set(publicInstance, this);
privatePublicInstanceMap.set(this, publicInstance);
};
PrivateClass.prototype.privateProperty = 'myPrivateProperty';
PrivateClass.prototype.privateMethod = function() {
var val = this.privateProperty;
// Get pubic instance and set public property.
var pubThis = _rp(this);
pubThis.publicProperty = 'bar';
};
PrivateClass.prototype.privateMethod2 = function() {
// Call ourselve with public instance instead.
if (this instanceof PrivateClass) {
return this.privateMethod.apply(_rp(this), arguments);
}
// "this" is is the public instance beyond this point.
this.publicProperty = 'baz';
};
var PublicClass = function PublicClass() {
var privateInstance = new PrivateClass();
privateInstance.linkWithPublicInstance(this);
};
PublicClass.prototype.publicProperty = 'foo';
PublicClass.prototype.publicMethod = function() {
// Get private instance.
var privThis = _p(this);
privThis.privateProperty = 'newPrivateValue';
// Call private method.
privThis.privateMethod();
};
// Only export the PublicClass
exports.PublicClass = PublicClass;
})(window);
@timdream
Copy link
Author

@julienw woot!

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