实现 new

function myNew(Ctr, ...args) {
  if (typeof Ctr !== "function") {
    throw new TypeError("Constructor must be a function");
  }
  // 创建原始对象
  // let obj = {};
  // 设置新对象的prototype
  // Object.setPrototypeOf(obj, Ctr.prototype);
  // 创建原始对象,Object.create可以以参数为prototype创建一个新对象
  let obj = Object.create(Ctr.prototype);
  const result = Ctr.apply(obj, args);
  // 判断一下,防止构造函数指定了返回值
  return result !== null &&
    (typeof result === "object" || typeof result === "function")
    ? result
    : obj;
}

实现 call,apply

call 是参数一个个传进去,apply 是参数以数组形式传进去

Function.prototype.myCall = function (context) {
  // 获取剩余参数
  let args = [...arguments].slice(1),
    // 定义Symbol类型的key
    key = Symbol("KEY"),
    result = null;
  // 如果不是object或者function类型,则装箱使其可以被增加属性
  !/^(object|function)$/i.test(typeof context)
    ? (context = Object(context))
    : null;
  context[key] = this;
  result = context[key](...args);
  delete context[key];
  return result;
};

bind,利用闭包暂存 this

Function.prototype.myBind = function (context, ...params) {
  let self = this;
  return function proxy(...args) {
    self.apply(context, params.concact(args));
  };
};