JavaScript 中的 this 指向详解
this 是 JavaScript 中一个非常关键但容易混淆的关键字,它的值取决于函数的调用方式。下面详细介绍 this 的各种指向情况。
1. 全局作用域下的 this
在全局作用域中:
console.log(this); // 浏览器中指向 window,Node.js 中指向 global
2.普通函数中的 this
在普通函数中:
function show() {
console.log(this);
}
show(); // 浏览器中为 window,严格模式下为 undefined
-
非严格模式下,
this默认指向全局对象。 -
严格模式 (
'use strict') 下,this为undefined。
3.对象方法中的 this
在对象方法中
const obj = {
name: 'Alice',
sayHi() {
console.log(this.name);
}
};
obj.sayHi(); // Alice
这里 this 指向调用该方法的对象 obj。
4.构造函数中的 this
在构造函数中
function Person(name) {
this.name = name;
}
const p = new Person('Bob');
console.log(p.name); // Bob
使用 new 关键字时,this 指向新创建的实例对象。
5.call、apply 和 bind 改变 this
function greet() {
console.log(this.name);
}
const user = { name: 'Charlie' };
greet.call(user); // Charlie
greet.apply(user); // Charlie
const boundGreet = greet.bind(user);
boundGreet(); // Charlie
-
call和apply立即调用函数,改变this。 -
bind返回一个新的函数,永久绑定this。
6.箭头函数中的 this
箭头函数中:
const obj = {
name: 'Dave',
sayHi: () => {
console.log(this.name);
}
};
obj.sayHi(); // undefined
- 箭头函数没有自己的
this,它会捕获定义时外层作用域的this。
一个正确的使用场景:
const obj = {
name: 'Eve',
sayHi() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
obj.sayHi(); // Eve
7.DOM 事件处理中的 this
const btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log(this); // 指向当前触发事件的 DOM 元素
});
-
使用普通函数,
this指向触发事件的元素。 -
使用箭头函数时,
this来自事件绑定时的词法作用域。
8.class 中的 this
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a sound');
}
}
const dog = new Animal('Dog');
dog.speak(); // Dog makes a sound
- 类中的方法默认使用严格模式,
this指向实例。
总结
| 场景 | this 指向 |
|---|---|
| 全局作用域 | 浏览器中为 window,严格模式为 undefined |
| 普通函数调用 | 非严格为全局对象,严格模式为 undefined |
| 对象方法调用 | 调用该方法的对象 |
| 构造函数 | 新创建的实例对象 |
call / apply / bind | 被显式指定的对象 |
| 箭头函数 | 定义时外层作用域的 this |
| DOM 事件处理器 | 普通函数为 DOM 元素,箭头函数为词法作用域 |
class 方法 | 实例对象 |