普通函数直接调用时this指向globalThis(非严格模式)或undefined(严格模式);隐式绑定仅发生在obj.method()形式;箭头函数无this,继承外层非箭头函数的this,且不可被call/apply/bind修改。

普通函数调用时 this 指向 globalThis(非严格模式)或 undefined(严格模式)
这是最常踩坑的场景:直接调用函数,比如 foo(),此时 this 不指向调用它的对象,而是根据执行上下文决定。浏览器中非严格模式下是 window,Node.js 是 global;严格模式下统一为 undefined。
容易误以为“函数写在对象里,调用时就自动绑定该对象”,但只要不是通过对象属性形式调用(即没写 obj.method()),就不会触发隐式绑定。
- 别写
const fn = obj.method; fn();—— 这会丢失this - 事件回调、定时器、Promise 回调里直接写
handler()也会掉this - React 类组件中不绑定方法,直接传
onClick={this.handleClick},点击时this是undefined(严格模式)
箭头函数没有自己的 this,它继承外层作用域的 this 值
箭头函数的 this 在定义时就确定了,无法被 call/apply/bind 修改,也不能作为构造函数使用。它只看外层第一个非箭头函数的 this 绑定。
常见误用:在对象方法里用箭头函数想访问当前对象,结果拿到的是外层(比如模块顶层或 class 构造函数)的 this。
立即学习“Java免费学习笔记(深入)”;
- 不要写
obj = { method: () => console.log(this) }——this不是obj - Vue 选项式 API 的
methods里写箭头函数,this拿不到 Vue 实例 - 类中写
handleClick = () => { ... }是 OK 的(靠 class 字段初始化语法捕获实例this),但这是靠语法糖,不是箭头函数“应该这么用”
call/apply/bind 显式绑定时,new 调用会忽略前两者,但 bind 返回的函数 new 时仍可被拦截
call 和 apply 是立即执行并强制指定 this;bind 返回新函数,其 this 被永久绑定。但注意:new 优先级高于显式绑定 —— 如果对一个已被 bind 的函数再用 new,this 会指向新实例,原绑定失效。
而 call/apply 在 new 场景根本不会发生,因为它们不是构造调用语法。
-
const bound = original.bind(obj); new bound()→this是新实例,不是obj -
original.call(obj)不能加new,语法错误 - 手写
bind时若要兼容new,得在返回函数里判断是否被new调用(检查this是否是目标函数的实例)
对象方法调用(隐式绑定)时,this 指向调用者,但赋值后立即失效
写成 obj.method() 时,this 是 obj;但只要中间有变量赋值这一步,比如 const m = obj.method; m(),就退化为普通函数调用规则。
这个“点号左边是谁”非常关键,且只看**调用时的表达式结构**,不看函数从哪来。
-
(obj.method)()和obj.method()等价,括号不打断隐式绑定 -
(0, obj.method)()或let m = obj.method; m()会丢失绑定 —— 因为逗号操作符和赋值都返回右值,不再带对象上下文 - 解构赋值同理:
const { method } = obj; method()→this失效
function foo() {
console.log(this);
}
const obj = { foo };
foo(); // 浏览器中输出 window 或 undefined(严格模式)
obj.foo(); // 输出 obj
const bar = obj.foo;
bar(); // 又回到第一行的行为
箭头函数的词法 this 和 new 对绑定的覆盖,是两个最容易被静态代码分析忽略的点。调试时如果发现 this 不是你预期的对象,先看调用形式有没有“断链”,再确认函数是不是箭头函数,最后检查有没有 new 干扰了你用 bind 设的意图。











