ES6 实现 call() 和 apply()

16,542 阅读1分钟

根据 原文链接 抄袭实现

call()

首先我们先来看一下 js 原生方法的实现形式

var obj = {
    name: "pig",
    age: 28
}

function name () {
    return this.name
}

name.call(obj)  // pig

根据返回形式 我们可以简单表现为

var obj = {
    name: 'pig',
    age: 28,
    fn: function name() {
        return this.name
    }
}

obj.fn() // pig

由上我们可以得知,call的主要步骤

  • 把函数 this 指向传入的对象 obj
  • 执行 fn 方法
  • 由于我们添加了 fn方法 ,所以需要删除 fn
// content 默认值设为 window
Function.prototype.myCall = function (content = window) {
  
  const fn = Symbol('fn')
  // 用this获取调用当前myCall的方法  再绑定到 content 上
  content[fn] = this
  // 获取 传入的参数 (从arguments对象里取)
  const args = [...arguments].slice(1)

  const newFunc = content[fn](...args)
  
  // 删除 content 上添加的方法
  delete content[fn]

  return newFunc
}

function bar(age,sex) {
  return {
    name: this.name,
    age,
    sex
  }
}
const obj = {
    name: '潘勇旭'
}

bar.myCall( obj, 28, "男" )   // {name: "潘勇旭", age: 28, sex: "男"}

apply()

apply()call() 实现方式类似,唯一的区别就是 第二个参数传入的是数组

Function.prototype.myApply = function (content = window) {

  const fn = Symbol('fn')
  content[fn] = this
  
  // 返回 传入的参数
  const args = arguments[1]

  const newFunc = args && args.length ? content[fn](...args) : content[fn]()
  
  // 删除 content 上添加的方法
  delete content[fn]

  return newFunc
}

function bar(age,sex) {
  return {
    name: this.name,
    age,
    sex
  }
}
const obj = {
    name: '潘勇旭'
}

bar.myApply( obj, [28, "男"] )   // {name: "潘勇旭", age: 28, sex: "男"}

有错误的地方,欢迎大家指正, 在下感激不尽。