手写 call bind

210 阅读1分钟

手写 call

function myCall(fn, context, ...args){
  // 挂上
  context.fn = fn;
  // 计算
  let result = context.fn(...args)
  // 删除
  delete context.fn;
  // 返回
  return result;
}

function add(z){
  return this.x + this.y + z;
}

 let a = {
   x: 1,
   y: 2
 }
 
myCall(add, a, 6)       //9

手写原生 bind

  function myBind(fn, context, ...args) {
  // 挂上
  context.fn = fn
  
  // 1. 参数一次传递
  if(args.length){
    // 计算
    let result = context.fn(...args)
    // 删除
    delete context.fn
    // 返回
    return function(){
      return result;
    }
  } else {
    // 2. curry 版
      //返回
    return function (...args){
      // 计算
      let result = context.fn(...args)
      // 删除
      delete context.fn
      // 返回
      return result;
    }
    
  }
  
}
// this 绑定与参数传递一起完成
let bindAdd = myBind(add, a, 1)
// 第二次调用仅仅是为了获取已经计算好的值
bindAdd()       //4

// this 绑定并返回绑定 this 之后的原函数的拷贝
let copyAdd = myBind(add, a)
// 传参并执行函数
copyAdd(5)      //8