普通函数调用时this指向全局对象(非严格模式)或undefined(严格模式);方法调用时指向点号左侧对象;构造函数中指向新实例;箭头函数无this,继承外层词法作用域。

普通函数调用时,this 指向全局对象(非严格模式)或 undefined(严格模式)
这是最容易踩坑的场景:直接写 foo() 调用函数,this 和函数定义在哪无关,只看「怎么被调用」。浏览器里非严格模式下它指向 window,Node.js 指向 global;加了 'use strict' 就是 undefined。
实操建议:
- 永远在模块顶部或函数开头加
'use strict',避免意外绑定到全局 - 别依赖
this在普通函数里有“合理”值——它大概率不是你想要的 - 如果真需要访问全局,显式写
window或globalThis,更清晰也更可靠
方法调用时,this 指向「点号左边的对象」
比如 obj.method(),this 在 method 内部就指向 obj。但注意:这个绑定只发生在调用那一刻,不是定义时。
常见错误现象:
立即学习“Java免费学习笔记(深入)”;
-
const fn = obj.method; fn();→this不再是obj,退回到上一条规则 -
setTimeout(obj.method, 100)→ 同样丢失this,因为setTimeout内部是普通调用
解决办法:
- 用箭头函数包装:
setTimeout(() => obj.method(), 100) - 用
.bind(obj)显式绑定 - 传入时用闭包:
setTimeout(function() { obj.method(); }, 100)
构造函数和 class 中,this 指向新创建的实例
new Foo() 或 new MyClass() 时,this 是那个刚分配内存、尚未初始化的对象。此时它还没执行构造函数体,但已经可以赋值属性。
关键差异:
-
class方法默认不绑定this,和对象字面量里的方法一样,单独提取就会丢失 - 类字段中的箭头函数(
handler = () => {})能自动绑定,是因为它在实例化时被赋值,且箭头函数不绑定自己的this - 不要在构造函数里对
this做异步操作后才返回——this已经是实例,但状态可能未就绪
箭头函数没有自己的 this,它沿用外层作用域的 this
箭头函数不创建执行上下文,也不接收调用时传入的 this。它的 this 是词法绑定的,由定义位置决定,和调用方式完全无关。
使用场景:
- 事件回调中保持组件实例引用:
button.addEventListener('click', () => this.handleClick()) - 避免在
map/filter回调里手动.bind(this)
容易忽略的点:
- 不能用
call/apply/bind强行改箭头函数的this,它们无效 - 如果外层是普通函数且
this已经是undefined(比如严格模式下的顶层箭头函数),那内层箭头函数的this也是undefined
真正难的不是记住规则,而是意识到「this 的值永远由调用方式决定,而不是函数怎么写的」。只要盯住那一行带括号的调用(xxx()),往前看最近的点号或 new,基本就能定位。其余时候,优先用箭头函数或显式绑定,比猜更省时间。











