mockBind

100 阅读1分钟

//V1

Function.prototype.bind2 = function () {
  const args = Array.from(arguments);
  const obj = args.shift();

  return () => this.apply(obj, args.concat(Array.from(arguments)));
};
// !!!!
// 完全错误 ,谨记箭头函数没有arguments和constructor

// V2

Function.prototype.bind2 = function () {
  const args = Array.from(arguments);
  const obj = args.shift();
  const self = this;
  return function () {
    self.apply(obj, args.concat(Array.from(arguments)));
  };
};

// 还是有问题,bind之后的函数可以被当做构造函数,构造函数this指向新实例

// function test(m,n){
//   console.log(`m:${m}---n:${n}`)
//   this.name=m
//   this.age=n
//   this.male=true
//   console.log("log this.a",a)

// }
// test.prototype.friend="xxx"

//V3

Function.prototype.bind2 = function () {
  const args = Array.from(arguments);
  const obj = args.shift();
  const self = this;
  //这里可以被new调用,该函数prototype应该指向原函数
  const fn = function () {
    return self.apply(
      this instanceof fn ? this : obj,
      args.concat(Array.from(arguments))
    );
  };
  // 这里还是有问题 修改fn的原型,原来的原型也会受影响
  fn.prototype = this.prototype;
  return fn;
};

//V4

Function.prototype.bind2 = function () {
  const args = Array.from(arguments);
  const obj = args.shift();
  const self = this;
  //这里可以被new调用,该函数prototype应该指向原函数
  const fn = function () {
    return self.apply(
      this instanceof fn ? this : obj,
      args.concat(Array.from(arguments))
    );
  };
  // 这里可以优化为create
  const fnNOP = function () {};
  fnNOP.prototype = this.prototype;
  fn.prototype = new fnNOP();
  return fn;
};

function MockCreate(proto) {
  function F() {}
  F.prototype = proto;
  return new F();
}

// V5

Function.prototype.bind2 = function () {
  const args = Array.from(arguments);
  const obj = args.shift();
  const self = this;
  const fn = function () {
    return self.apply(
      this instanceof fn ? this : obj,
      args.concat(Array.from(arguments))
    );
  };

  fn.prototype = Object.create(this.prototype);
  return fn;
};