箭头函数没有自己的this,直接捕获定义时外层第一个普通函数的this值,且无法被call/apply/bind修改;普通函数的this则由调用时的上下文决定。

箭头函数的 this 不是动态绑定的,它根本就没有自己的 this,而是直接沿用定义时所在词法作用域中最近一层普通函数的 this 值。
不绑定、不继承、只捕获
箭头函数在定义那一刻就“快照”了外层普通函数的 this,之后无论怎么调用(包括作为对象方法、被 call/apply/bind 调用),都无法改变它。
- 普通函数的
this是运行时决定的,看“谁调用”;箭头函数的this是定义时决定的,看“在哪写” -
call、apply、bind对箭头函数完全无效——传进去的thisArg被忽略 - 如果外层没有普通函数(比如直接在全局或模块顶层定义),那就捕获全局作用域的
this(浏览器中是window,严格模式下是undefined)
常见陷阱场景
容易误以为箭头函数会自动指向调用它的对象,但其实它根本不关心调用位置。
- 对象字面量里写箭头方法:
const obj = { name: 'A', f: () => console.log(this.name) }→obj.f()中的this不是obj,而是外层作用域的this - 类字段中用箭头函数声明方法:
class C { handleClick = () => console.log(this.val) }→ 这里的this是类构造时的上下文(通常为实例),但**仅因构造函数执行时它被定义**,不是因为“类方法”规则 - 定时器/事件回调中用箭头函数,能保持外层
this,是因为它捕获的是setTimeout外层函数的this,不是因为“回调特殊”
如何判断箭头函数的 this
从箭头函数定义的位置出发,向外逐层查找:找到第一个非箭头函数,它的 this 就是答案。
- 如果箭头函数写在普通函数内部 →
this等于该普通函数执行时的this - 如果写在类的方法里 →
this等于该方法被调用时的实例(即类方法的this) - 如果写在模块顶层或全局 →
this是全局对象或undefined(取决于是否严格模式)
对比普通函数:一个直观例子
下面两段代码行为完全不同:
const obj = { x: 100 };
function outer() {
console.log('outer this:', this.x); // 100(若 outer.call(obj))
const regular = function() { console.log('regular this:', this.x); };
const arrow = () => console.log('arrow this:', this.x);
regular(); // this 是全局(或 undefined),输出 undefined
arrow(); // this 是 outer 的 this,输出 100
}
outer.call(obj);
关键不在箭头函数“多聪明”,而在它压根没参与 this 绑定流程——它只是读取了外层已确定的值。











