JavaScript中curry柯里化函数绑定对象方法丢失上下文问题
问题成因
- curry函数内部返回的是箭头函数,箭头函数没有自身的this绑定,会继承定义时外层作用域的this,此处外层作用域this为全局对象(严格模式下为undefined),无法跟随调用场景动态绑定到
obj对象上。 - 最终执行原函数时使用
fun(...args)的直接调用方式,未绑定执行上下文,普通函数直接调用时this默认指向全局对象(严格模式下为undefined),因此obj.b内部的this.a读取失败得到undefined,最终拼接结果为undefinedbar。
另外你提供的测试代码存在一处笔误:obj.foobar是curry返回的函数,需要添加括号调用obj.foobar()才会得到执行结果,直接打印obj.foobar只会输出函数本身。
修复方案
方案1:修改curry函数支持动态this绑定
调整curry函数的实现,改用普通函数接收调用时的this上下文,执行原函数时绑定该上下文:
function curry(fun, ...args){ if(args.length >= fun.length) { return fun.call(this, ...args) } // 返回普通函数,可捕获调用时的this上下文 return function(...rest) { return curry.call(this, fun, ...args, ...rest) } }
修改后测试代码运行结果符合预期:
const obj = { a: 'foo', b: function (a) { return this.a + a; } } obj.foobar = curry(obj.b, 'bar'); console.log(obj.foobar()) // 输出 foobar const foobar = curry(obj.b) console.log(foobar.call(obj, 'bar')) // 输出 foobar
方案2:手动绑定固定上下文(无需修改curry函数)
如果不需要上下文动态切换,可以在传入函数时手动绑定this:
obj.foobar = curry(obj.b.bind(obj), 'bar'); console.log(obj.foobar()) // 输出 foobar const foobar = curry(obj.b.bind(obj)) console.log(foobar('bar')) // 输出 foobar
内容的提问来源于stack exchange,提问作者Pisk
相关产品推荐
相关产品推荐

