JS编写call、apply、bind函数

127 阅读1分钟

通过JS仿照call、apply、bind实现mycall、myapply、mybind三个函数

1.mycall函数

// 给所有的函数添加一个mycall方法。
Function.prototype.mycall = function (thisArgs, ...args) {
  // 获取被执行函数
  var fn = this

  // 把thisArgs转成对象类型
  thisArgs = (thisArgs !== null && thisArgs !== undefined) ? Object(thisArgs) : window

  // 调用被执行函数
  thisArgs.fn = fn
  const res = thisArgs.fn(...args)
  delete thisArgs.fn

  return res
}

function foo() {
  console.log('foo函数被执行', this);
}

function sum(num1, num2) {
  return num1 + num2
}

// 默认进行隐式绑定
foo.mycall()

const res = sum.mycall({}, 10, 20)
console.log(res);

2.myapply函数

// 实现myapply函数
Function.prototype.myapply = function (thisArgs, argArray) {
  const fn = this

  thisArgs = (thisArgs !== null && thisArgs !== undefined) ? Object(thisArgs) : window

  thisArgs.fn = fn
  argArray = argArray || []
  const res = thisArgs.fn(...argArray)

  delete thisArgs.fn

  return res
}

function sum(num1, num2) {
  console.log('sum', this, num1, num2);
  return num1 + num2
}

function foo1(num) {
  return num
}

function foo2() {
  console.log('foo2');
}

const res1 = sum.myapply('a', [1, 2])
console.log(res1);

const res2 = foo1.myapply('a', [1])
console.log(res2);

foo2.myapply()

3.mybind函数

Function.prototype.mybind = function (thisArgs, ...argArray) {
  const fn = this

  thisArgs = (thisArgs !== null && thisArgs !== undefined) ? Object(thisArgs) : window

  function proxyFn(...args) {
    thisArgs.fn = fn
    const finalArgs = [...argArray, ...args]
    const res = thisArgs.fn(...finalArgs)
    delete thisArgs.fn
    return res
  }

  return proxyFn
}

function foo() {
  console.log('foo被执行', this);
  return 20
}

function sum(num1, num2, num3, num4) {
  console.log(num1, num2, num3, num4);
  return num1 + num2 + num3 + num4
}

const bar = foo.mybind('abc')
const res1 = bar()
console.log(res1);

const newSum = sum.mybind('abc', 1, 2)
const res2 = newSum(3, 4)
console.log(res2);