JavaScript 中的 `this` 指向详解

264 阅读2分钟

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') 下,thisundefined

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.callapplybind 改变 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
  • callapply 立即调用函数,改变 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 方法实例对象