返回

一文看懂前端必备函数:call、apply 和 bind

前端

前端必备函数:call、apply 和 bind

在 JavaScript 中,call、apply 和 bind 函数都是用于改变函数的调用上下文(this 的值)的。它们都可以接受一个对象作为第一个参数,该对象将成为函数的调用上下文。不同之处在于,call 和 apply 函数需要将函数的参数作为第二个参数和后续参数传入,而 bind 函数则可以将参数作为第二个参数和后续参数传入,也可以在稍后调用函数时传入。

用法

call

function greet(name) {
  console.log(`Hello, ${name}!`);
}

const person = {
  name: 'John'
};

greet.call(person, 'Jane'); // Hello, Jane!

apply

function greet(name) {
  console.log(`Hello, ${name}!`);
}

const person = {
  name: 'John'
};

const args = ['Jane'];

greet.apply(person, args); // Hello, Jane!

bind

function greet(name) {
  console.log(`Hello, ${name}!`);
}

const person = {
  name: 'John'
};

const boundGreet = greet.bind(person);

boundGreet('Jane'); // Hello, Jane!

区别

  • call 和 apply 都需要将函数的参数作为第二个参数和后续参数传入,而 bind 函数则可以将参数作为第二个参数和后续参数传入,也可以在稍后调用函数时传入。
  • call 和 apply 函数会立即执行函数,而 bind 函数则不会立即执行函数,而是返回一个新的函数,该函数可以在稍后调用时传入参数并执行。

闭包

闭包是一个函数及其周围环境的组合。闭包允许函数访问其周围环境中的变量,即使该函数已经执行完毕。

在 JavaScript 中,闭包可以通过使用 call、apply 或 bind 函数来创建。

例如,以下代码创建了一个闭包,该闭包包含一个名为 counter 的变量:

function createCounter() {
  let counter = 0;

  return function() {
    return ++counter;
  };
}

const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter2()); // 1
console.log(counter2()); // 2

在上面的代码中,createCounter 函数返回了一个新的函数,该函数可以访问 createCounter 函数中的 counter 变量。即使 createCounter 函数已经执行完毕,counter1 和 counter2 变量仍然可以访问 counter 变量。

总结

call、apply 和 bind 函数都是用于改变函数的调用上下文(this 的值)的。它们都可以接受一个对象作为第一个参数,该对象将成为函数的调用上下文。不同之处在于,call 和 apply 函数需要将函数的参数作为第二个参数和后续参数传入,而 bind 函数则可以将参数作为第二个参数和后续参数传入,也可以在稍后调用函数时传入。