new,apply,call,bind方法

new

  • new被调用后做了什么
    • 创建一个空对象,该对象的__proto__属性应该指向new调用的构造函数的prototype
    • 将this指向这个空对象
    • 执行new调用的构造函数代码块内容
    • 根据调用的构造函数是否有返回值判断,如果返回值存在且typeof检测类型为object类型,则返回该结果,如果不存在返回值或者返回值为基础数据类型,则返回创建的对象
  • 自己实现的myNew方法
function myNew(ctor, ...rest) {
  if (typeof ctor !== 'function') {
    throw `${ctor} is not a constructor`
  }
  const obj = {}
  obj.__proto__ = Object.create(ctor.prototype)
  const result = ctor.apply(obj, rest)
  if (
    (typeof result === 'object' && result !== null) ||
    typeof result === 'function'
  )
    return result
  return obj
}

apply

  • 调用apply函数时,apply函数都做了什么
    • 将this指向第一个参数,如果参数不存在,则默认为window
    • 执行调用apply方法的函数,apply的第二个参数为数组,里边的内容为函数的参数
Function.prototype.myApply = function (thisArg = window, argArray = []) {
  if (typeof this !== 'function') {
    throw new Error('Not a function')
  }
  thisArg.fn = this
  const result = thisArg.fn(...argArray)
  delete thisArg.fn
  return result
}
myApply定义在Function的原型对象上(this指向问题:调用myApply方法的是一个函数,因此this是直接指向函数的)
判断this是否是函数,不是函数就抛出错误
将目标对象thisArg上的fn指向this
调用thisArg.fn,此时fn函数内的this就指向了thisArg
删除thisArg上的fn方法
fn函数结果需要作为myApply的结果进行返回

call

  • 调用call函数时,call函数都做了什么
    • 将this指向第一个参数,如果参数不存在则默认window
    • 第二个及以后的所有参数为调用call函数的函数的参数
Function.prototype.myCall = function (thisArg = window, ...arg) {
  if (typeof this !== 'function') {
    throw new Error('Not a function')
  }
  thisArg.fn = this
  const result = thisArg.fn(...arg)
  delete thisArg.fn
  return result
}
将myCall添加到Function的原型对象上
判断当前this是不是一个函数,不是函数就抛出错误
将this绑定到目标对象上,作为目标对象的方法fn
通过thisArg调用fn,此时fn的this就指向了thisArg
删除thisArg上的fn方法
返回函数执行结果作为myCall的执行结果

bind

  • 调用bind函数时,bind函数都做了什么
    • 第一个参数改变this指向,如果不存在则默认window
    • 第二个及以后的参数为调用bind函数的函数的参数,该部分参数会在调用bind方法返回的fBound函数传参前边作为固定参数加入到fBound函数中
Function.prototype.myBind = function (thisArg = window, ...args) {
  if (typeof this !== 'function') {
    throw new Error('Not a function')
  }
  let self = this
  const fBound = function () {
    self.apply(thisArg, [...args, ...arguments])
  }
  return fBound
}
将myBind添加到Function的原型对象上
判断当前this是不是一个函数,不是函数就抛出错误
定义一个函数fBound,函数内部调用外部this函数的apply方法,参数为目标this对象thisArg和myBind函数传入的参数args和fBound函数的参数合并成的数组,通过此举将调用myBind函数的函数通过apply方法改变了其this指向并执行
返回fBound函数 使用的时候,因为myBind函数返回的是一个函数,需要再次调用,此时就会执行fBound函数,里边的apply函数就会执行,拿到this指向改变的结果

posted on 2024-12-05 18:58  shenhf  阅读(6)  评论(0编辑  收藏  举报

导航