Skip to content

Instantly share code, notes, and snippets.

@RianFuro
Created December 11, 2016 19:44
Show Gist options
  • Save RianFuro/9ede9a80c7eb1bcb2bfe254f1d6fdfd5 to your computer and use it in GitHub Desktop.
Save RianFuro/9ede9a80c7eb1bcb2bfe254f1d6fdfd5 to your computer and use it in GitHub Desktop.
Playing around with ES6 proxies to implement object access wrapping losely based on pythons decorator functionality (@before, @after)
function getAllFuncs(obj) {
var props = [],
orig = obj;
do {
props = props.concat(Object.getOwnPropertyNames(obj));
} while ((obj = Object.getPrototypeOf(obj)) && obj != Object.prototype);
return props.sort().filter(function(e, i, arr) {
if (e!=arr[i+1] && typeof orig[e] == 'function' && e != 'constructor') return true;
});
}
var wrap = module.exports = function (base, proxies) {
var base_functions = getAllFuncs(base.prototype)
return function (...args) {
args.unshift(undefined)
var obj = new (Function.prototype.bind.apply(base, args))()
let proxy = new Proxy(obj, {
get (receiver, name) {
if (name in proxies && 'get' in proxies[name])
return proxies[name].get(receiver, name)
else return receiver[name]
},
set (receiver, name, value) {
if (name in proxies && 'set' in proxies[name])
proxies[name].set(receiver, name, value)
else receiver[name] = value
}
})
base_functions.forEach(n => {
obj[n] = new Proxy(obj[n], {
apply (receiver, that, args) {
if (receiver.name in proxies && 'apply' in proxies[receiver.name])
return proxies[receiver.name].apply(receiver, that, args)
else return receiver.apply(that, args)
}
})
})
return proxy
}
}
wrap.log = function (base, options = { prefix: '[DEBUG]' }) {
var base_functions = getAllFuncs(base.prototype)
return function (...args) {
args.unshift(undefined)
var obj = new (Function.prototype.bind.apply(base, args))()
let proxy = new Proxy(obj, {
get (receiver, name) {
console.log(options.prefix, 'GET', name, receiver)
return receiver[name]
},
set (receiver, name, value) {
console.log(options.prefix, 'SET', name, value, receiver)
receiver[name] = value
}
})
base_functions.forEach(n => {
obj[n] = new Proxy(obj[n], {
apply (receiver, that, args) {
console.log(options.prefix, 'CALL', receiver.name, args, that)
return receiver.apply(that, args)
}
})
})
return proxy
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment