手撕 call,apply,bind

55 阅读1分钟

手撕 call,apply,bind

原生 call、apply、bind 的作用

JavaScript 中的 callapplybind 是 Function 原型上的方法,用于操作函数的 this 指向。

call

call 方法调用一个函数,并指定函数内 this 的值和参数列表。

func.call(thisArg, arg1, arg2, ...)
  • 立即执行函数
  • 第一个参数为函数内 this 的指向
  • 从第二个参数开始依次传入函数

apply

apply 方法调用一个函数,并指定函数内 this 的值和以数组形式提供的参数。

func.apply(thisArg, [argsArray]);
  • 立即执行函数
  • 第一个参数为函数内 this 的指向
  • 第二个参数为包含所有参数的数组

bind

bind 方法创建一个新函数,该函数在调用时,会将 this 设为提供的值。

func.bind(thisArg, arg1, arg2, ...)
  • 返回一个新函数,不会立即执行
  • 第一个参数为函数内 this 的指向
  • 可以预设参数,这些参数会优先传入函数

手写实现

call

Function.prototype.myCall = function (thisArg, ...args) {

  thisArg = thisArg || (typeof window !== "undefined" ? window : global);

  const fn = Symbol("fn");

  thisArg[fn] = this;

  const result = thisArg[fn](...args);

  delete thisArg[fn];

  return result;
};

apply

Function.prototype.myApply = function (thisArg, args) {
  thisArg = thisArg || window;

  const fn = Symbol();

  thisArg[fn] = this;

  let result;
  if (args) {
    if (!Array.isArray(args)) {
      throw new TypeError("Arguments must be an array");
    }
    result = thisArg[fn](...args);
  } else {
    result = thisArg[fn]();
  }

  delete thisArg[fn];

  return result;
};

bind

Function.prototype.mybind = function (context, ...args) {
  return (...newArgs) => {
    return this.call(context, ...args, ...newArgs);
  };
};