privaskey, prototype-friendly privacy
by plus5keen
HTML
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h2>Output</h2>
<div class="output"></div>
<p>additional output goes to development console</p>
</body>
</html>
JavaScript
// AMD-to-global shim
function amdToGlobal(global, key) {
if (!global || global.define) { return; }
var oldDefine = global[key];
global[key] = global.define;
global.define = function(cb) { // TODO add deps?
global[key] = cb();
global.define = oldDefine;
};
}
amdToGlobal(window, 'privaskey');
// privaskey
// Simple Prototype-Friendly Privacy
// by Cory Watson
// call privaskey(obj) to access obj private data
// call privaskey.make() to create a private privacy object for truly private data
// call privaskey.makeFriend(i) to share a privaskey object with another module, allowing it to access your private data
// use multiple privaskey objects to share only a portion of your private data
define(function() {
'use strict';
var idCounter = 0;
function getId() {
return '__PRIVASKEY.' + String(idCounter++) + '.' + Math.floor(Math.random() * 65536) + '__';
}
var has = Object.prototype.hasOwnProperty;
function make() {
var p, id = getId();
p = function privacyGet(obj) {
return obj[id] || (obj[id] = {});
};
p.make = make;
p.makeFriend = function(i) {
if (!i || i < 0) { i = 1; }
return function makeFriend() {
if (!i) { return; }
i--;
return p;
};
};
p.makeProp = function(key) {
return function(value) {
if (typeof value === 'undefined') {
return p(this)[key];
}
return p(this)[key] = value;
};
};
p.makeProps = function(keyMap) {
var result = {};
for(var key in keyMap) {
if (has.call(keyMap, key)) {
result[key] = p.makeProp(keyMap[key]);
}
}
return result;
};
return p;
}
return make();
});
// Design...