Skip to content

Instantly share code, notes, and snippets.

@bga
Created March 31, 2011 11:56
Show Gist options
  • Save bga/896235 to your computer and use it in GitHub Desktop.
Save bga/896235 to your computer and use it in GitHub Desktop.
/*
Very simple. Uses [gs]etters and caller. Precache '_method in Class' relations using unique `Class.jbId_` and `_method.jbOwnerClassIdMap_`.
*/
(function()
{
var nextClassId = 1;
var _methodInClass = function(_fn, Class)
{
var classId = Class.jbId_;
if(!classId)
{
var classId = Class.jbId_ = nextClassId++;
for(var i in Class.prototype)
{
if(!{}.hasOwnProperty.call(Class.prototype, i)) continue;
var _method = Class.prototype[i];
if(_method.constructor !== Function) continue;
var ownerClassIdMap = _method.jbOwnerClassIdMap_ || (_method.jbOwnerClassIdMap_ = {})
ownerClassIdMap[classId] = 1;
}
}
return _fn.jbOwnerClassIdMap_ && _fn.jbOwnerClassIdMap_[classId];
};
var _defPrivateField = function(obj, name, v)
{
obj.__defineGetter__(name, function()
{
var _caller = arguments.callee.caller;
if(_methodInClass(_caller, obj.constructor))
return v;
else
throw ReferenceError(name);
});
obj.__defineSetter__(name, function(nv)
{
var _caller = arguments.callee.caller;
if(_methodInClass(_caller, obj.constructor))
v = nv;
else
throw ReferenceError(name);
});
};
var Class = function()
{
_defPrivateField(this, 'foo', 1);
};
Class.prototype = {
constructor: Class,
_bar: function()
{
this.foo = 2;
return this.foo;
}
};
var c = new Class();
console.log(c._bar()); // 2
try
{
console.log(c.foo); // oops! `foo` is private
}
catch(err)
{
console.log(err);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment