返回

this 的千姿百态:深入理解JavaScript中的this用法

前端

this的本质

this在JavaScript中是一个特殊的,它指向正在执行代码的当前对象。this的指向取决于代码的执行上下文,可以是全局对象、函数对象、对象实例或其他对象。

在严格模式下,全局对象this是undefined,而在非严格模式下,全局对象this是window对象。

this的几种用法

1. 全局this

全局this是指在全局作用域中执行的代码的this指向。在严格模式下,全局this是undefined,而在非严格模式下,全局this是window对象。

// 全局this指向window对象
console.log(this === window); // true

2. 上下文this

上下文this是指在函数中执行的代码的this指向。上下文的this是由函数的调用方式决定的。

  • 直接调用 :当函数直接调用时,this指向全局对象(非严格模式)或undefined(严格模式)。
// 直接调用,this指向全局对象
function greet() {
  console.log(this); // window
}

greet();
  • 作为对象的方法调用 :当函数作为对象的方法调用时,this指向该对象。
// 作为对象的方法调用,this指向该对象
const person = {
  name: 'John Doe',
  greet: function() {
    console.log(this); // { name: 'John Doe', greet: [Function: greet] }
  }
};

person.greet();
  • 使用apply()、call()或bind()调用 :使用apply()、call()或bind()调用函数时,可以显式地指定this指向。
// 使用apply()调用函数,this指向传入的对象
const person = {
  name: 'John Doe',
};

function greet() {
  console.log(this); // { name: 'John Doe' }
}

greet.apply(person);

// 使用call()调用函数,this指向传入的对象
function greet() {
  console.log(this); // { name: 'John Doe' }
}

greet.call(person);

// 使用bind()调用函数,this指向传入的对象
const boundGreet = greet.bind(person);

boundGreet();

3. 构造函数this

构造函数this是指在构造函数中执行的代码的this指向。构造函数this指向新创建的对象。

// 构造函数this指向新创建的对象
function Person(name) {
  this.name = name;
}

const person = new Person('John Doe');

console.log(person); // { name: 'John Doe' }

4. 箭头函数this

箭头函数this是指在箭头函数中执行的代码的this指向。箭头函数的this指向与外层作用域的this指向相同。

// 箭头函数this指向与外层作用域的this指向相同
const person = {
  name: 'John Doe',
  greet: () => {
    console.log(this); // { name: 'John Doe', greet: [Function: greet] }
  }
};

person.greet();

this的使用技巧和最佳实践

  • 尽量避免使用箭头函数,因为箭头函数的this指向与外层作用域的this指向相同,这可能会导致一些意外的情况。
  • 在构造函数中,使用this来引用对象实例的属性和方法。
  • 在对象的方法中,使用this来引用对象本身。
  • 在全局作用域中,使用this来引用window对象。
  • 如果你想显式地指定this指向,可以使用apply()、call()或bind()方法。