apply、call、bind详解

66 阅读1分钟

apply

apply(thisArg, argsArray)

接收两个参数,第一个参数为绑定this的对象,第二个参数为类数组对象,用于指定调用 func 时的参数。apply的返回值是一个立即调用函数。

Function.prototype.MyApply(obj, args){
  // 如果调用者不是函数,则退出
  if(typeof this !== 'function'){
    throw Error('error')
  }
  // 把调用者当成新绑定对象的一个方法,如果传入的值不合法则新绑定为window的this
  const context = obj || window
  context.fn = this
  // 这里直接调用
  const result = context.fn(...args)
  return result
}

call

call(thisArg, arg1, arg2, /* …, */ argN) 与apply的区别是用于指定调用func的参数必须分开传入。

Function.prototype.MyCall(obj, ...args){
  // 如果调用者不是函数,则退出
  if(typeof this !== 'function'){
    throw Error('error')
  }
  // 把调用者当成新绑定对象的一个方法,如果传入的值不合法则新绑定为window的this
  const context = obj || window
  context.fn = this
  // 这里直接调用
  const result = context.fn(...args)
  return result
}

bind

bind(thisArg, arg1, arg2, /* …, */ argN) 该方法会创建一个新函数,不会立即执行。可以传入一系列指定的参数,这些参数会插入到调用新函数时传入的参数的前面。

Function.prototype.MyBind(obj, args){
  // 如果调用者不是函数,则退出
  if(typeof this !== 'function'){
    throw Error('error')
  }
  // 保存原函数的引用
  fn = this

  // 返回一个函数
  return function Fn(afterArgs){
    // 判断是否用new关键字构造
    return fn.apply(
      this instanceof Fn ? this : obj,
      args.concat(afterArgs)
    )
  }
}