Skip to content

Instantly share code, notes, and snippets.

@bga
Created November 29, 2010 19:43
Show Gist options
  • Save bga/720460 to your computer and use it in GitHub Desktop.
Save bga/720460 to your computer and use it in GitHub Desktop.
// from https://gist.github.com/613924
Proxy._noopHandler = function noopHandler(obj) {
return {
getOwnPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(obj, name);
// a trapping proxy's properties must always be configurable
desc.configurable = true;
return desc;
},
getPropertyDescriptor: function(name) {
var desc = Object.getPropertyDescriptor(obj, name); // not in ES5
// a trapping proxy's properties must always be configurable
desc.configurable = true;
return desc;
},
getOwnPropertyNames: function() {
return Object.getOwnPropertyNames(obj);
},
getPropertyNames: function() {
return Object.getPropertyNames(obj); // not in ES5
},
defineProperty: function(name, desc) {
Object.defineProperty(obj, name, desc);
},
delete: function(name) { return delete obj[name]; },
fix: function() {
if (Object.isFrozen(obj)) {
return Object.getOwnPropertyNames(obj).map(function(name) {
return Object.getOwnPropertyDescriptor(obj, name);
});
}
// As long as obj is not frozen, the proxy won't allow itself to be fixed
return undefined; // will cause a TypeError to be thrown
},
has: function(name) { return name in obj; },
hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
get: function(receiver, name) { return obj[name]; },
// bad behavior when set fails in non-strict mode
set: function(receiver, name, val) { obj[name] = val; return true; },
enumerate: function() {
var result = [];
for (name in obj) { result.push(name); };
return result;
},
keys: function() { return Object.keys(obj); }
};
};
var _cast = function(obj, Class)
{
if(!(obj instanceof Class))
return null;
var proxy = Proxy._noopHandler(obj)
proxy.get = function(r, name)
{
var v = Class.prototype[name];
if(v instanceof Function)
return v.bind(obj);
else
return obj[name];
}
return Proxy.create(proxy, Class.prototype);
};
var A = function(a)
{
this.a = a;
};
A.prototype._fn = function()
{
console.log(this.a, 'A');
};
var B = function(a)
{
A.call(this, a);
};
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
B.prototype._fn = function()
{
console.log(this.a, 'B');
};
var b = new B('test');
var a = _cast(b, A);
b._fn(); // test B
a._fn(); // test A
console.log(a.a); // test
console.log(a instanceof A); // true
console.log(_cast(b, Function) + ''); // null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment