通过ES6代理实现扩展对象方法的功能,但具有TypeError如下:
const extendMethod = (obj) => (key) => (f) => {
const handler = {
get: (target, propKey, receiver) => {
const targetValue = Reflect.get(target, propKey, receiver);
return key === propKey
? f(target.valueOf())
: (typeof targetValue === "function")
? (...args) => Object(target.valueOf())[propKey](...args)
: targetValue;
}
};
return new Proxy(obj, handler);
};
const a = { x: 5 };
const f = (target) => { console.log(target); };
const a1 = extendMethod(a)("log")(f);
a1.log(); //{x:5}
//TypeError: a1.log is not a function
如何修改代码以避免错误?谢谢。
答案 0 :(得分:2)
该脚本期望a1.log
评估为 function ,因为该脚本将继续被调用为a1.log();
。但与行
? f(target.valueOf())
,运行f
函数,然后将调用f
的输出返回到外部。但是f
的输出为undefined
,因为(外部)f
不返回任何内容。
抑制错误的一种方法是返回不执行任何操作的函数:
? (f(target.valueOf()), () => void 0)
const extendMethod = (obj) => (key) => (f) => {
const handler = {
get: (target, propKey, receiver) => {
const targetValue = Reflect.get(target, propKey, receiver);
return key === propKey
? (f(target.valueOf()), () => void 0)
: (typeof targetValue === "function")
? (...args) => Object(target.valueOf())[propKey](...args)
: targetValue;
}
};
return new Proxy(obj, handler);
};
const a = { x: 5 };
const f = (target) => { console.log(target); };
const a1 = extendMethod(a)("log")(f);
a1.log(); //{x:5}
或者您可能只是访问 a1.log
属性(将函数称为副作用)而不调用它:
const extendMethod = (obj) => (key) => (f) => {
const handler = {
get: (target, propKey, receiver) => {
const targetValue = Reflect.get(target, propKey, receiver);
return key === propKey
? f(target.valueOf())
: (typeof targetValue === "function")
? (...args) => Object(target.valueOf())[propKey](...args)
: targetValue;
}
};
return new Proxy(obj, handler);
};
const a = { x: 5 };
const f = (target) => { console.log(target); };
const a1 = extendMethod(a)("log")(f);
a1.log; //{x:5}
如果外部f
函数 did 返回一个函数(即,如果它是高阶函数),则您将能够正常使用a1.log()
:
const extendMethod = (obj) => (key) => (f) => {
const handler = {
get: (target, propKey, receiver) => {
const targetValue = Reflect.get(target, propKey, receiver);
return key === propKey
? f(target.valueOf())
: (typeof targetValue === "function")
? (...args) => Object(target.valueOf())[propKey](...args)
: targetValue;
}
};
return new Proxy(obj, handler);
};
const a = { x: 5 };
const f = (target) => {
console.log(target);
return arg => {
console.log('inner fn! ' + arg);
};
};
const a1 = extendMethod(a)("log")(f);
a1.log('foo');