前端小技巧: TS实现bind函数,call函数,以及apply函数

bind 函数实现

  • 返回一个新函数,但是不执行

    Function.prototype.customBind = function (context:any, ...bindArgs: any[]) {
      // context 是bind传入的this
      // bindArgs 是bind传入的各个参数
      const self = this // 当前函数本身
      return function(...args:any[]) {
        const newArgs = bindArgs.concat(args)
        return self.apply(context, newArgs)
      }
    }
    
    function fn(this:any, a:any, b:any, c:any) {
      console.info(this, a, b, c)
    }
    
    const fn1 = fn.customBind({x: 100}, 10)
    fn1(20, 30)
    
  • 实际上,原生js中,bind 底层用的就是 apply

  • bind是返回一个新函数,不执行

  • call和apply是会立刻执行的

call 函数实现

Function.prototype.customCall = function (context: any, ...args: any[]) {
  if (context) context = globalThis
  if (typeof context !== 'object') context = new Object(context) // 值类型转化为对象
  const fnKey = Symbol()
  context[fnKey] = this // this 就是当前的函数
  const res = context[fnKey](..args) // 绑定了this 这是立即执行
  delete context[fnKey]
  return res
}

function fn(this:any, a:any, b:any, c:any) {
  console.log(this, a, b, c)
}

fn.customCall({x:100}, 1, 2, 3) // 这里会立即执行

apply 函数实现

Function.prototype.customApply = function (context: any, args: any[] = []) {
  if (context) context = globalThis
  if (typeof context !== 'object') context = new Object(context) // 值类型转化为对象
  const fnKey = Symbol()
  context[fnKey] = this // this 就是当前的函数
  const res = context[fnKey](..args) // 绑定了this 这是立即执行
  delete context[fnKey]
  return res
}

function fn(this:any, a:any, b:any, c:any) {
  console.log(this, a, b, c)
}

fn.customApply({x:100}, 1, 2, 3) // 这里会立即执行

总结

  • 绑定 this
  • 传入执行参数
  • 分析:
    • 如何在函数执行时,绑定this
    • 如:const obj = {x: 100, fn() {this.x}}
    • 执行obj.fn(), 此时fn内部的this就指向obj
    • 可以借次来实现函数绑定 this
  • 用 call 实现 apply, 用 apply 实现 call 不可取
  • 原生 call apply 的 this 如果是值类型sing,会被 new Object(…)
  • Symbol 的作用,是防止属性之间的冲突

你可能感兴趣的:(Javascript,Typescript,Web,前端,bind,call,apply)