返回

搞懂Apply, Call, Bind用法及源码实现,轻松掌握区别!

前端

深入理解 JavaScript 中的 Apply、Call 和 Bind

函数的 This 指向

JavaScript 函数中的 this 指向函数调用的上下文对象。当函数作为对象方法调用时,this 指向该对象。否则,this 指向全局对象(浏览器中的 window)。

Apply、Call 和 Bind

Apply、Call 和 Bind 都是 JavaScript 函数,可以改变函数的 this 指向并传递参数。它们之间的主要区别在于传递参数的方式。

  • Apply: Apply 接受两个参数:要改变 this 指向的对象和一个包含要传递给函数参数的数组。
  • Call: Call 也接受两个参数:要改变 this 指向的对象和一个包含要传递给函数的第一个参数,后续参数逐个列出。
  • Bind: Bind 与 Apply 和 Call 不同,它不立即执行函数,而是返回一个新的函数。这个新函数的 this 指向被绑定为第一个参数,并且可以接受任意数量的参数。

示例

以下示例展示了如何使用 Apply、Call 和 Bind:

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

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

greet('Hello'); // Hello, undefined!
greet.apply(person, ['Hello']); // Hello, John Doe!
greet.call(person, 'Hello'); // Hello, John Doe!
const boundGreet = greet.bind(person);
boundGreet('Hello'); // Hello, John Doe!

源码实现

Apply、Call 和 Bind 的源码实现相当简单:

// Apply
Function.prototype.apply = function(thisArg, argArray) {
  return this.call(thisArg, ...argArray);
};

// Call
Function.prototype.call = function(thisArg, ...args) {
  thisArg = thisArg || globalThis;
  thisArg.fn = this;
  const result = thisArg.fn(...args);
  delete thisArg.fn;
  return result;
};

// Bind
Function.prototype.bind = function(thisArg, ...args) {
  const bound = (...boundArgs) => {
    this.apply(thisArg, [...args, ...boundArgs]);
  };
  bound.prototype = Object.create(this.prototype);
  return bound;
};

总结

Apply、Call 和 Bind 是 JavaScript 中非常有用的函数,可以灵活地使用函数。它们之间的区别在于传递参数的方式。根据需要,你可以选择使用哪个函数。

常见问题解答

  1. Apply、Call 和 Bind 的用途是什么?
    它们用于改变函数的 this 指向并传递参数。

  2. Apply、Call 和 Bind 有什么区别?
    Apply 使用一个数组传递参数,Call 使用逐个参数,Bind 返回一个绑定 this 指向的新函数。

  3. 何时使用 Apply?
    当参数已存储在数组中时。

  4. 何时使用 Call?
    当参数已知且数量较少时。

  5. 何时使用 Bind?
    当需要创建一个具有特定 this 指向的新函数时。