实现call、apply、bind

85 阅读1分钟

实现call

Function.prototype.mycall = function (context, ...agrs) {
  //判断是否为undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  let fnSymbol = Symbol(); //保证context的值独一无二
  context[fnSymbol] = this; //保证this指向
  let fn = context[fnSymbol](...agrs);
  delete context[fnSymbol];
  return fn
}

实现apply

Function.prototype.myapply = function (context, agrs) {
  //判断是否为undefined或者null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  let fnSymbol = Symbol();
  context[fnSymbol] = this;
  let fn = context[fnSymbol](...agrs);
  return fn
}

实现bind

Function.prototype.mybind = function (context) {
  //判断是否为undefined或者null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  self = this;
  return function (...agrs) {
    return self.apply(context, agrs);
  }
}

测试

function fightingTo (to) {
  console.log(`${this.name} fighting to ${to}`)
}

var Jerry = {
  name: 'Jerry'
}
fightingTo.mycall(Jerry, 'Tom')
//Jerry fighting to Tom.

var Foo = {
  name: 'Foo'
}
fightingTo.myapply(Foo, ['Bar'])
//Foo fighting to Bar.

var XYZ = {
  name: 'XYZ'
}
var say = fightingTo.mybind(XYZ)
say('ABC')
//XYZ fighting to ABC.