JS手写系列1: 手写实现bind,call,apply

262 阅读1分钟

手写实现bind

bind函数的特点

  • 改变this的指向
  • 第一个参数为this的指向,后面的参数为函数接收的参数的值
  • 不会改变函数的返回值

手写实现

bind函数存在与Function的原型上,因此我们的myBind也绑定在原型上

思路一:通过apply函数改变原函数的指向

Function.prototype,myBind = function(context,...args){
    const self = this
    return function(){
        return self().apply(thisVal,args)
    }
}

思路二:

  • 不传入第一个参数,那么默认为window
  • 改变了 this 指向,让新的对象可以执行该函数。那么思路是否可以变成给新的对象添加一个函数,然后在执行完以后删除
Function.prototype.myBind = function (context, ...args) {
   const symbolFn = Symbol('fn')
   context[symbolFn] = this
   return function(){
     context[symbolFn](...args)
     delete context[symbolFn]
   }
}

手写实现call

call函数的特点

call()  方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

手写实现

实现思路:

  • 将方法挂载到传入的上下文中
  • 将挂载以后的方法调用
  • 将挂载的这个方法删除
Function.prototype.myCall = function(context,...args){
    context = context || window
    context.fn = this
    context.fn(...args)
    delete context.fn
}

手写实现apply

apply函数的特点

apply()  方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

手写实现

实现思路:

  • apply接收的参数为数组,传参不为数组则报错
  • 将方法挂载到传入的上下文中
  • 将挂载以后的方法调用
  • 将挂载的这个方法删除
Function.prototype.myApply = function (context = window,args = []){
 const key = Symbol()
   context[key] = this
   context[key](...args)
   delete context[key]
}