Proxy working
by Pedro Moreira
HTML
https://jsfiddle.net/pedsmoreira/fz6d6p5j/48/#collaborate
JavaScript
function isFunction(value) {
return typeof value === 'function';
}
function isFunctionWithSingleOrZeroArgs(value) {
return isFunction(value) && value.length <= 1;
}
function proxyArrayFunctionCurry(arrayFunction, property) {
const fn = function(...args) {
const result = arrayFunction(function(item) {
return item[property](...args);
});
return result;
};
return new Proxy(fn, {
get: function(target, property) {
return target()[property];
}
});
}
function proxyArrayFunction(array, fn) {
const boundFn = fn.bind(array);
return new Proxy(fn, {
get: function(target, property) {
if (property === '_fn') return fn;
if (property === 'bind') return null;
if (fn.length === 0) {
const fnResult = boundFn();
const value = fnResult[property];
if (value.bind) {
return value.bind(fnResult);
}
return value;
}
const reflector = (array[0] || {})[property];
if (typeof reflector === 'function') {
return proxyArrayFunctionCurry(boundFn, property);
}
return boundFn((item) => item[property]);
},
apply: function(target, thisArg, argumentsList) {
if (isFunction(thisArg)) {
thisArg = thisArg();
}
return target.bind(thisArg)(...argumentsList);
}
})
}
function jewell(target, method) {
const fn = target[method];
Object.defineProperty(target, method, {
get: function() {
return proxyArrayFunction(this, fn);
}
})
}
function jewellPrototype(target) {
Object.getOwnPropertyNames(target.prototype).forEach((property) => {
if (property === 'constructor') return;
const value = target.prototype[property];
if (isFunctionWithSingleOrZeroArgs(value)) {
console.info(`${target.name}.${property} jewelled`)
jewell(target.prototype, property);
}
})
}
class Animal {
constructor(name, nickname) {
this.name = name;
this.nickname = nickname;
}
...