nfssuzukaze / Blog

0 stars 0 forks source link

call 与 apply 的模拟实现 #23

Open nfssuzukaze opened 3 years ago

nfssuzukaze commented 3 years ago

1. call 的模拟实现

1.1 call 的初步实现

调用 call 所传递的第一个参数表示的是: 函数执行时的 this 指向. 同时, 后续传入的参数是函数原本执行时就所需的参数 根据这两个需求, 我们可以写出如下代码

Function.prototype.call = Function.prototype.call || function(new_this) {
  const arg = []
  for (let i = 1; i < arguments.length; i ++) {
    arg.push(arguments[i])
  }
  new_this.fn = this
  const result = new_this.fn(...arg)
  delete new_this.fn
  return result
}

1.2 call 的进一步实现

当调用 call 所传递的第一个参数是 null 或 undefined 时, 函数的 this 指向为 window 若传入的第一个参数是基础类型, 则会在函数中转化为引用类型

Function.prototype.call = Function.prototype.call || function(new_this) {
  new_this = Object(new_this) || window
  const arg = []
  for (let i = 1; i < arguments.length; i ++) {
    arg.push(arguments[i])
  }
  new_this.fn = this
  const result = new_this.fn(...arg)
  delete new_this.fn
  return result
}

2. apply 的模拟实现

2.1 apply 的初步模拟

Function.prototype.apply = Function.prototype.apply || function(new_this) {
  const arg = arguments[1]
  // 获取传入的数组
  new_this.fn = this
  // 将原函数挂载到 this 指定的对象上
  const result = new_this.fn(...arg)
  // 使用扩展运算符将传入的数组展开传参
  // 并用 result 接收函数的返回值
  delete new_this.fn
  // 删除掉挂载在对象上的原函数引用
  return result
  // 返回调用函数的返回值
}

2.2 apply 的进一步模拟

当调用 apply 所传递的第一个参数是 null 或 undefined 时, 函数的 this 指向为 window 若传入的第一个参数是基础类型, 则会在函数中转化为引用类型

Function.prototype.apply = Function.prototype.apply || function(new_this) {
  new_this = Object(new_this) || window
  const arg = arguments[1]
  // 获取传入的数组
  new_this.fn = this
  // 将原函数挂载到 this 指定的对象上
  const result = new_this.fn(...arg)
  // 使用扩展运算符将传入的数组展开传参
  // 并用 result 接收函数的返回值
  delete new_this.fn
  // 删除掉挂载在对象上的原函数引用
  return result
  // 返回调用函数的返回值
}