返回

聊聊 Javascript 中this 的妙用,附带apply、call、bind详解

前端

在JavaScript中,this是一个,它指向函数执行时所属的对象,简单来说,this就是函数执行时所属的对象。当调用一个函数时,这个函数的this值被确定,并且在函数执行期间保持不变。理解this的用法和实质,是掌握JavaScript函数调用的关键。

this的用法

this的用法主要有以下几种:

  1. 方法调用中的this: 当一个函数作为对象的方法被调用时,this指向该对象。例如:
const person = {
  name: "John Doe",
  greet: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.greet(); // Output: "Hello, my name is John Doe"

在这个例子中,当person.greet()被调用时,this指向person对象,因此console.log()输出"Hello, my name is John Doe"。

  1. 构造函数中的this: 当一个函数被用作构造函数时,this指向新创建的对象。例如:
function Person(name) {
  this.name = name;
}

const person1 = new Person("John Doe");

console.log(person1.name); // Output: "John Doe"

在这个例子中,当new Person("John Doe")被调用时,this指向新创建的person1对象,因此console.log()输出"John Doe"。

  1. 事件处理程序中的this: 当一个函数被用作事件处理程序时,this指向触发该事件的元素。例如:
const button = document.querySelector("button");

button.addEventListener("click", function() {
  console.log(this); // Output: <button>...</button>
});

button.click();

在这个例子中,当button.click()被调用时,this指向触发该事件的button元素,因此console.log()输出<button>...</button>

apply、call、bind

在JavaScript中,还有三个方法可以改变函数的this指向:apply()、call()和bind()。

  1. apply(): apply()方法可以将一个函数应用到一个给定的this值。语法如下:
functionName.apply(thisValue, [args]);

例如:

const person = {
  name: "John Doe"
};

function greet() {
  console.log(`Hello, my name is ${this.name}`);
}

greet.apply(person); // Output: "Hello, my name is John Doe"

在这个例子中,apply()方法将greet()函数应用到person对象上,因此console.log()输出"Hello, my name is John Doe"。

  1. call(): call()方法与apply()方法类似,但它接受单个参数作为this值,而不是数组。语法如下:
functionName.call(thisValue, arg1, arg2, ..., argN);

例如:

const person = {
  name: "John Doe"
};

function greet() {
  console.log(`Hello, my name is ${this.name}`);
}

greet.call(person); // Output: "Hello, my name is John Doe"

在这个例子中,call()方法将greet()函数应用到person对象上,因此console.log()输出"Hello, my name is John Doe"。

  1. bind(): bind()方法可以创建一个新的函数,该函数的this值被固定为给定的值。语法如下:
const newFunction = functionName.bind(thisValue);

例如:

const person = {
  name: "John Doe"
};

function greet() {
  console.log(`Hello, my name is ${this.name}`);
}

const boundGreet = greet.bind(person);

boundGreet(); // Output: "Hello, my name is John Doe"

在这个例子中,bind()方法创建了一个新的函数boundGreet,该函数的this值被固定为person对象,因此boundGreet()调用时,console.log()输出"Hello, my name is John Doe"。

理解this的实质

要理解this的实质,关键在于理解JavaScript的执行上下文。每个函数都有自己的执行上下文,执行上下文包含了该函数的局部变量、参数、this值等信息。当一个函数被调用时,会创建一个新的执行上下文,并且该函数的this值被确定为该执行上下文的this值。

例如:

function greet() {
  console.log(this.name);
}

const person = {
  name: "John Doe"
};

person.greet(); // Output: "John Doe"

在这个例子中,当person.greet()被调用时,会创建一个新的执行上下文,并且greet()函数的this值被确定为该执行上下文的this值。由于该执行上下文属于person对象,因此this.name输出"John Doe"。

结语

this是JavaScript中一个非常重要的概念,理解this的用法和实质,是掌握JavaScript函数调用的关键。apply()、call()和bind()三个方法可以改变函数的this指向,从而实现更灵活的函数调用。