传递含this的JavaScript函数作为参数时bind/apply失效求解
解决方案
问题核心是你用了箭头函数作为自定义函数传入——箭头函数的this是词法绑定的,会固定在定义它时的上下文,无法通过apply/call/bind修改,所以executeNow里的apply根本改不了箭头函数的this指向,导致this.parameter拿不到值。
针对类库场景,给你三个可行方案:
方案1:引导用户传入普通函数
箭头函数不适合需要动态绑定this的场景,类库可以明确说明:用户需要传入普通函数,这样executeNow里的apply就能把this绑定到object上。
修改用户侧的调用代码:
executeMeLater(function() { // 用普通函数代替箭头函数 console.log(this.parameter); // 此时this指向object,能拿到"hello!" }).executeNow();
类库代码不需要改动,这个方案最简单,但需要用户配合使用普通函数。
方案2:把父对象作为参数传给自定义函数
如果要兼容用户用箭头函数的情况,类库可以在执行自定义函数时,把object作为参数传进去,用户通过参数访问属性,不用依赖this:
修改类库的executeNow方法:
const object = { parameter: undefined, execute: undefined, executeNow: function() { // 把当前对象作为参数传给execute函数 this.execute(this); } };
用户侧不管用箭头还是普通函数,都能通过参数访问属性:
// 箭头函数写法 executeMeLater((obj) => { console.log(obj.parameter); // 输出"hello!" }).executeNow(); // 普通函数写法也兼容 executeMeLater(function(obj) { console.log(obj.parameter); // 同样输出"hello!" }).executeNow();
这个方案对用户更友好,不用限制函数类型,推荐使用。
方案3:类库自动绑定函数上下文(仅兼容普通函数)
如果用户坚持要用this访问属性,且类库想帮用户处理绑定,可以在设置object.execute时,把函数绑定到object:
修改类库的executeMeLater函数:
function executeMeLater(func) { object.parameter = "hello!"; // 把func绑定到object,确保执行时this指向object object.execute = func.bind(object); return object; };
但注意:这个方法只对普通函数有效,箭头函数的this还是无法被修改,所以用户如果传箭头函数,还是得用方案2的参数方式。
内容的提问来源于stack exchange,提问作者The Fox
相关产品推荐
相关产品推荐

