手动实现call、apply、bind

124 阅读1分钟

call

Function.prototype.myCall = function (context = window, ...args) {
//  判断当前this是否是函数,防止Function.prototype.myCall直接调用
  if (this === Function.prototype) {
    return undefined
  }
//  context是可选参数,如果为传,默认为window
  const context = context || window
//  为context创建一个symbol(保证不会重名)的属性,将当前函数赋值给这个属性
  const fn = Symbol()
  context[fn] = this
//  处理函数,传入第一个参数后的其余参数
  const result = context[fn](...args)
// 调用函数后删除该symbol属性
  delete context[fn]
  return result
}

apply

Function.prototype.myApply = function (context = window, args) {
  if (this === Function.prototype) {
    return undefined
  }
  const context = context || window
  const fn = Symbol()
  let result
  if (Array.isArray(args)) {
    result = context[fn](...args)
  } else {
    result = context[fn]()
  }
  delete context[fn]
  return result
}

bind

Function.prototype.myBind = function (context, ...args) {
  if (this === Function.prototype) {
    throw new TypeError('Error')
  }
  const _this = this
  return function f(...args1) {
    if (this instanceof f) {
      return new _this(...args, ...args1)
    } else {
      return _this.apply(context, args.concat(...args1))
    }
  }
}