JavaScript 中的 this 指向函数被调用时的执行上下文对象,而非定义时所在对象;普通调用时非严格模式下为全局对象(浏览器中为 window),严格模式下为 undefined;对象方法调用时 this 指向该对象;箭头函数无自有 this,继承外层非箭头函数的 this;new、call、apply、bind 可显式控制 this。

JavaScript 中的 this 不是指“函数定义时所在的对象”,而是“函数被调用时的执行上下文对象”——这个判断必须在每次调用时动态计算,不能靠代码位置猜。
普通函数调用时的 this 指向全局或 undefined
在非严格模式下,直接调用函数(如 foo()),this 指向全局对象(浏览器中是 window);严格模式下是 undefined。这是最容易误判的场景。
常见错误现象:this 在回调里突然变成 window 或 undefined,尤其在事件监听、定时器、数组方法(如 map、forEach)中传入普通函数时。
- 避免方式:用箭头函数(不绑定自己的
this)、显式绑定(bind/call/apply)、或改用对象方法调用形式 - 注意 Node.js 环境中全局对象是
global,不是window - ES Module 脚本默认启用严格模式,所以顶层普通函数调用的
this是undefined
对象方法调用决定 this 绑定到该对象
当函数作为对象属性被调用(如 obj.method()),this 指向 obj。但只看调用形式,不看函数如何定义或赋值。
立即学习“Java免费学习笔记(深入)”;
const obj = {
name: 'Alice',
say() {
console.log(this.name); // 'Alice'
}
};
const fn = obj.say;
fn(); // this 是 undefined(严格模式),不是 obj!
obj.say(); // this 是 obj
关键点:
-
this只由「谁点出来的」决定,不是「谁定义的」 - 一旦把方法赋给变量(
fn = obj.say),就丢失了调用主体,变成普通调用 - 解构赋值也会触发相同问题:
const { say } = obj; say();同样丢失this
箭头函数没有自己的 this,继承外层作用域
箭头函数不创建自己的 this,它会沿作用域链向上查找最近的非箭头函数的 this 值。因此它无法通过 call、apply、bind 改变 this。
const obj = {
name: 'Bob',
regular() {
console.log(this.name); // 'Bob'
const arrow = () => console.log(this.name); // 'Bob'
arrow();
}
};
obj.regular();
适用场景:
- 避免在
setTimeout、Promise.then、addEventListener回调中手动bind(this) - 类中定义事件处理器时(
class X { handleClick = () => { ... } }) - 但不要在需要动态
this的地方用箭头函数,比如想让方法能被不同对象复用时
new 调用和 call/apply/bind 显式控制 this
new Fn() 会让 this 指向新创建的实例;Fn.call(obj, ...)、Fn.apply(obj, [...])、Fn.bind(obj) 则强制指定 this 值。
容易踩的坑:
-
bind返回的是新函数,必须调用才生效:obj.method.bind(other)(),漏掉末尾()就没执行 -
call和apply立即执行,区别只在参数传法:call用逗号分隔,apply用数组 - 箭头函数无法被
call/apply/bind修改this,传进去的值会被忽略
真正难的不是记住规则,而是意识到 this 的值永远取决于「函数怎么被调用」,而不是「函数怎么被写」。哪怕同一个函数,在不同调用形式下 this 可能完全不同。调试时别盯着函数体,先看调用表达式左侧是什么。










