普通函数直接调用时,非严格模式下this指向全局对象,严格模式下为undefined;对象方法调用时this指向该对象,但提取后会丢失;箭头函数无this,继承外层;new和call/apply/bind可显式控制this。

普通函数调用时 this 指向全局对象或 undefined
在非严格模式下,function foo() { console.log(this); } 直接调用 foo(),this 指向 window(浏览器)或 globalThis(Node.js);严格模式下则为 undefined。这点极易被忽略,尤其在封装工具函数时——你以为在操作某个上下文,实际却在污染全局或触发 TypeError。
实操建议:
- 始终开启严格模式(
"use strict"),避免隐式绑定带来的不确定性 - 不要依赖非严格模式下的
window绑定,现代代码应显式传参或使用箭头函数替代 - 单元测试中单独运行函数(不通过对象调用),验证
this是否符合预期
对象方法调用时 this 指向调用它的对象
当写成 obj.method(),this 就是 obj。但一旦把方法抽出来赋值给变量,比如 const fn = obj.method; fn();,就退化为上一种情况——this 不再是 obj。
常见错误现象:Uncaught TypeError: Cannot read property 'x' of undefined,尤其在事件回调、定时器、Promise 回调里丢失上下文。
立即学习“Java免费学习笔记(深入)”;
解决方式(按推荐顺序):
- 用
bind显式绑定:setTimeout(obj.method.bind(obj), 100) - 改用箭头函数包装:
setTimeout(() => obj.method(), 100) - 在类中用字段语法定义箭头函数方法(ES2022+):
method = () => { ... } - 避免解构方法:
const { method } = obj;是高危操作,除非你立刻bind或包装
箭头函数没有自己的 this,沿作用域链向上找
箭头函数不绑定 this,它直接继承外层函数执行时的 this 值。这意味着它无法通过 call/apply/bind 改变 this,也不能作为构造函数使用。
典型误用场景:
- 在对象字面量中写箭头函数方法:
const obj = { fn: () => console.log(this) }—— 这里的this是定义时的外层上下文,不是obj - 试图用
setTimeout(obj.arrowFn.bind(obj), 100)——bind无效,因为箭头函数无视所有显式绑定
正确做法:需要动态 this 就用普通函数;需要固化外层 this(如 React 类组件中处理事件)才用箭头函数。
new 调用和 call/apply/bind 的 this 行为
new Foo() 时,this 指向新创建的实例对象;Foo.call(obj, ...) 则强制让 this 指向 obj。这两者优先级最高,能覆盖其他规则。
注意点:
-
bind返回的函数,即使再bind一次,也无法改变第一次绑定的this(返回的是“硬绑定”函数) -
call和apply是立即执行,而bind返回新函数,适合预设参数 + 后续调用 - 箭头函数不能被
new,会报TypeError: xxx is not a constructor
最易被忽略的细节:class 内部的普通方法(非箭头)在被提取后,this 依然会丢失——class 并不自动绑定方法,这是设计使然,不是 bug。











