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 值,优先级高于默认绑定规则。
fn.call(obj, arg1, arg2):立即执行,参数逐个传入fn.apply(obj, [arg1, arg2]):立即执行,参数以数组形式传入const boundFn = fn.bind(o
bj, 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))this 指向组件实例,但事件处理函数需手动绑定(或用类字段语法)this,尤其在异步链(如 Promise.then)中真正难的不是记住规则,而是意识到 this 的绑定发生在「调用时刻」而非「定义时刻」;任何脱离调用上下文去猜 this 的行为,都容易出错。调试时,第一反应不应该是“为什么不是我想要的”,而是“这个函数此刻是被谁调用的”。