核心规则
this指向当前调用函数的那个对象(谁调用,this就指向谁)。
常见场景
1. 普通函数调用
函数独立调用时,this默认指向 全局对象(浏览器中是 window,Node.js 中是 global)。
function show() {
console.log(this); // 浏览器中输出:window
}
show();
严格模式下,this是 undefined。
2. 对象方法调用
函数作为对象的方法被调用时,this指向 调用该方法的对象。
const user = {
name: '小明',
sayHi() {
console.log(this.name); // 输出:小明
}
};
user.sayHi();
3. 构造函数调用
通过 new调用构造函数时,this指向 新创建的实例对象。
function Person(name) {
this.name = name; // this 指向新实例
}
const p = new Person('小红');
4. 箭头函数
箭头函数没有自己的 this,它的 this继承自定义时所在的外部作用域。
const obj = {
name: '小李',
say: () => {
console.log(this.name); // 输出 undefined(这里 this 指向外层,可能是 window)
}
};
obj.say();
5. 事件处理函数
在 DOM 事件中,this通常指向 触发事件的元素。
button.addEventListener('click', function() {
console.log(this); // 输出:<button>元素
});
6. 通过 call / apply / bind 显式绑定
可以手动指定 this的指向。
通过 call, apply, bind 方法,可以强制指定函数执行时的 this 值。
call 和 apply:立即调用函数,并指定 this 和参数。
bind:不会立即调用函数,而是返回一个绑定了指定 this 值的新函数。
function introduce(lang1, lang2) {
console.log(`My name is ${this.name} and I know ${lang1} and ${lang2}`);
}
const student = { name: 'Bob' };
// 使用 call
introduce.call(student, 'JavaScript', 'Python');
// 输出: "My name is Bob and I know JavaScript and Python"
// 使用 apply
introduce.apply(student, ['Java', 'C++']);
// 输出: "My name is Bob and I know Java and C++"
// 使用 bind
const boundIntroduce = introduce.bind(student, 'Go');
boundIntroduce('Rust'); // 输出: "My name is Bob and I know Go and Rust"
// 非常适合用在回调函数中,防止 this 丢失
一句话总结
- 普通函数:看调用方式,默认
window(严格模式undefined)。 - 对象方法:指向调用它的对象。
- 构造函数:指向新实例。
- 箭头函数:指向定义时的外层
this,不受调用方式影响。 - call/apply/bind:可手动改变
this指向。