call、apply和bind的实现

109 阅读1分钟

call

Function.prototype.myCall = function (context, ...args) {
  // 装箱
  context = Object(context ?? window);

  const key = Symbol();
  context[key] = this;
  const result = context[key](...args);
  delete context[key];
  return result;
};

apply

Function.prototype.myApply = function (context, args = []) {
  // 装箱
  context = Object(context ?? window);
  
  const key = Symbol();
  context[key] = this;
  const result = context[key](...args);
  delete context[key];
  return result;
};

bind

不考虑箭头函数的情况

Function.prototype.myBind = function (context, ...args) {
  // 装箱
  context = Object(context ?? window);

  const fn = this;
  const key = Symbol();

  function f(...innerArgs) {
    if (this instanceof fn) {
      // 当做构造函数使用
      this[key] = fn;
      this[key](...args, ...innerArgs);
      delete this[key];
      return this;
    } else {
      // 普通函数调用
      context[key] = fn;
      const result = context[syn](...args, ...innerArgs);
      delete context[key];
      return result;
    }
  }

  f.prototype = this.prototype;

  return f;
};