Skip to content

Instantly share code, notes, and snippets.

@tvcutsem
Created October 8, 2012 18:18
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 tvcutsem/3854020 to your computer and use it in GitHub Desktop.
Save tvcutsem/3854020 to your computer and use it in GitHub Desktop.
membranes and getPrototypeOf
load('reflect.js'); // https://github.com/tvcutsem/harmony-reflect/blob/master/reflect.js
function makeMembrane(initTarget) {
var cache = new WeakMap();
var revoked = false;
function wrap(obj) {
if (Object(obj) !== obj) return obj; // primitives are passed through
var wrapper = cache.get(obj);
if (wrapper) return wrapper;
wrapper = Proxy(obj, Proxy(obj, { // "double lifting"
get: function(target, trapName) {
if (revoked) throw new TypeError("membrane revoked");
return function(target /*, ...args*/) { // generic trap
var args = Array.prototype.slice.call(arguments, 1).map(wrap);
return wrap(Reflect[trapName].apply(undefined, [target].concat(args)));
}
}
}));
cache.set(obj, wrapper);
return wrapper;
}
function revoke() { revoked = true; }
return {revoke: revoke, target: wrap(initTarget)};
}
// David's example, updated to work with above membrane code:
function C(){};
var membrane = makeMembrane(C);
var wrappedC = membrane.target;
// Thanks to the wrapping get trap, we have:
print(wrappedC.prototype !== C.prototype);
// Now, consider:
var wrappedCInstance = new wrappedC(); // created a cInstance as target
// Because of the getPrototypeOf invariant, we have:
print(Object.getPrototypeOf(wrappedCInstance) === Object.getPrototypeOf(cInstance));
// the above line will throw: TypeError: prototype value does not match
print("done!");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment