JavaScript中this指向函数调用时的上下文对象而非定义时作用域:普通调用时非严格模式下为全局对象、严格模式下为undefined;对象方法调用时指向调用者对象;箭头函数继承外层this;call/apply/bind可显式绑定this;事件回调等易因调用方式改变this。

JavaScript 中的 this 不指向定义时的作用域,而是取决于函数「怎么被调用」——这是绝大多数困惑的根源。
普通函数调用时,this 指向全局对象或 undefined
在非严格模式下,独立调用的函数(如 foo())中 this 指向 window(浏览器)或 globalThis(Node.js);严格模式下为 undefined。
- 常见错误现象:
this突然变成undefined,控制台报错「Cannot read property of undefined」 - 容易踩的坑:把对象方法赋值给变量后调用,例如
const fn = obj.method; fn();→ 此时已丢失原始this - 验证方式:在函数内打印
console.log(this),注意是否处于严格模式("use strict")
对象方法调用时,this 指向调用它的那个对象
当函数作为对象属性被点号(.)或方括号([])调用时,this 绑定到该对象。
const user = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`); // this → user
}
};
user.greet(); // Hello, Alice
- 注意:仅看函数定义位置没用,关键看调用时的「左侧对象」:
obj.fn()中this是obj,obj.nested.fn()中this是obj.nested - 箭头函数不遵循此规则——它没有自己的
this,而是继承外层作用域的this - 嵌套对象中容易误判:若
obj.a.b.fn(),this是obj.a.b,不是obj
call、apply、bind 显式控制 this
这三个方法允许你手动指定函数执行时的 this 值,优先级高于默认绑定规则。
立即学习“Java免费学习笔记(深入)”;
-
fn.call(obj, arg1, arg2):立即执行,参数逐个传入 -
fn.apply(obj, [arg1, arg2]):立即执行,参数以数组形式传入 -
const boundFn = fn.bind(obj, arg1):返回新函数,this永久绑定为obj,可后续调用 - 注意:
bind两次不会覆盖——第一次绑定后,this已固化,第二次无效 - 箭头函数无法被这三者改变
this,因为它的this是词法绑定的
事件处理器和回调中 this 容易丢失
DOM 事件监听器中,this 默认指向触发事件的元素(如 button),但一旦用箭头函数或解构赋值,就可能意外丢失。
const btn = document.querySelector('button');
const handler = function() {
console.log(this); // this → btn 元素
};
btn.addEventListener('click', handler);
// ❌ 错误写法(this 变成 window 或 undefined)
btn.addEventListener('click', () => handler());
// ❌ 更隐蔽的错误(解构后调用)
const { handleClick } = obj;
btn.addEventListener('click', handleClick); // this → undefined(非严格模式下是 window)
- 解决方案:用
bind、改用箭头函数包装、或直接内联调用(e => handler(e)) - React 类组件中,生命周期方法里的
this指向组件实例,但事件处理函数需手动绑定(或用类字段语法) - 现代实践中,更推荐用闭包或参数传递代替依赖
this,尤其在异步链(如Promise.then)中
真正难的不是记住规则,而是意识到 this 的绑定发生在「调用时刻」而非「定义时刻」;任何脱离调用上下文去猜 this 的行为,都容易出错。调试时,第一反应不应该是“为什么不是我想要的”,而是“这个函数此刻是被谁调用的”。











