欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

js实现手写call、apply、bind

程序员文章站 2022-07-14 14:25:22
...

1.最简单的call

Function.prototype.myCall = function(thisArg, ...args) {
  // 1.获取需要被执行的函数,此时的this就是函数
  let fn = this
  // 2.对thisArg转成对象类型(防止它传入的是非对象类型)    Object(thisArg)可以把基本数据类型变成对象类型
  thisArg = thisArg !== undefined && thisArg !== null ? Object(thisArg) : window
  // 因为需要改变指向,所以赋值为一个属性
  thisArg.fn = fn
  // 3.调用需要被执行的函数
  thisArg.fn(...args)
  // 删除这个多余的属性   打印的时候这属性还在
  delete thisArg.fn
}

function foo(num1, num2) {
  console.log('foo', num1, num2, this)
}

foo.myCall(0, 1, 2, 3, 4, 5, 6, 7)

2.有一点不一样的apply

// 这里参数可以来个默认参数,防止没传参数时,解构会报错
Function.prototype.myApply = function(thisArg, args = []) {
  // 1.获取到要执行的函数
  let fn = this
  // 2.处理绑定的thisArg
  thisArg = thisArg !== null && thisArg !== undefined ? Object(thisArg) : window
  // 3.执行函数
  thisArg.fn = fn
  thisArg.fn(...args)
  delete thisArg.fn
}

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

foo.myApply({ name: 123 }, [1, 2, 3])

3.最后的bind

Function.prototype.myBind = function(thisArg, ...args) {
  // 这里需要使用箭头函数,谁调用了myBind,this指向谁
  // 如果用 return function(){}   调用时,this变为了window
  return (...argArray) => {
    // 1.绑定this
    let fn = this
    console.log(fn)
    // 2.判定thisArg
    thisArg =
      thisArg !== undefined && thisArg !== null ? Object(thisArg) : window

    thisArg.fn = fn
    thisArg.fn(...[...args, ...argArray])
    delete thisArg.fn
  }
}

function foo(num1, num2, num3) {
  console.log('foo被执行', this, num1, num2, num3)
}

let bar = foo.myBind('123', 1, 2)

bar(3)