箭头函数使用.call或.apply后this仍为undefined的原因及解决办法
箭头函数无法通过.call/.apply修改this的原因及替代方案
代码示例
var obj = { method : () =>{ console.log(this) } } obj.method.apply(obj)
问题
我尝试使用.call或.apply为箭头函数设置this上下文,但this始终为undefined。我了解箭头函数具有词法this绑定,但仍希望通过.call或.apply改变上下文,请问原因是什么?有没有替代方案?
原因
箭头函数的this是词法绑定的,它会直接继承定义时所在外层作用域的this,完全忽略调用时的上下文。不管用.call、.apply还是.bind,这些方法传入的第一个参数都会被直接忽略,根本无法修改箭头函数的this指向。
在你的代码里,对象字面量不会创建新作用域,箭头函数method实际定义在全局作用域下,所以它的this就是全局作用域的this——在严格模式下全局this为undefined,因此打印结果就是undefined。
替代方案
1. 改用普通函数
如果需要动态改变this指向,直接把箭头函数替换为普通函数即可。普通函数的this由调用方式决定,.call/.apply可以正常修改它的上下文:
var obj = { method: function() { console.log(this) } } obj.method.apply(obj) // 此时this指向obj
2. 手动传参模拟上下文
如果一定要保留箭头函数,可以通过传递参数的方式模拟“上下文”,把需要的对象直接传入函数:
var obj = { method: (context) => { console.log(context) } } obj.method(obj) // 直接传入obj作为模拟上下文
也可以兼容.call/.apply的调用方式,利用剩余参数处理:
var obj = { method: function(...args) { const context = args.shift() const arrowFunc = () => { console.log(context) } arrowFunc() } } obj.method.apply(null, [obj]) // 传入obj作为模拟的上下文
3. 提前绑定外层作用域的this
如果箭头函数需要固定指向某个特定上下文,可以在定义它的外层作用域提前绑定this,比如:
var obj = { init: function() { this.method = () => { console.log(this) } } } obj.init() obj.method() // this指向obj
这里箭头函数定义在init方法内部,继承了init调用时的this(也就是obj),后续调用时this会始终指向obj。
内容的提问来源于stack exchange,提问作者MOHAMED SIKKANDAR AFZAL M
相关产品推荐
相关产品推荐

