手写 call,apply,bind

112 阅读1分钟

捋捋思路,**call **和 apply 的区别其实就是接收参数的形式不同,call是接收若干参数,apply则是将参数组成一个数组来接收。 bindapply的区别是bind不会立即执行,而是返回一个函数。

他们的核心作用其实都是改变函数执行时的this指向。

话不多说,上代码:

call :

//call
Function.prototype.myCall = function(context){
    context = context || window  //若未传递参数,则默认绑定到window
    context.fn = this //绑定函数到指定对象
    let args = Array.prototype.slice.call(arguments,1)	//截取参数,从第二个开始为函数参数		
    const res =  context.fn(...args) //通过指定对象调用该函数,则该函数的this绑定到指定对象
    delete context.fn
    return res
}

实现思路: myCall函数接收一个 context 表示 this 要绑定到的对象,该函数内的 this 即调用myCall的函数, 将该函数绑定为 context 对象上的一个成员并且执行它。余下参数通过延展运算符放入参数中, 这样在执行时该函数的 this 便指向调用它的 context 了。

apply:

//apply
Function.prototype.myApply = function(context,args){
    context = context || window
    args = args || []  //若未传递参数,则为空数组
    context.fn = this	
    const res =  context.fn(...args)
    delete context.fn
    return res
}

实现思路: 和 call 大差不差,主要是余下参数的处理。

bind:

//bind
Function.prototype.myBind = function(context){
    context = context || window
    let args = Array.prototype.slice.call(arguments,1)
    args = args || []
    return  newArgs => 	this.apply(context,[...args,newArgs]) //通过apply将函数绑定到指定对象,并且将新旧参数传入,返回一个箭头函数(箭头函数内的this就是外层函数的this)
}

实现思路: 与 apply 的区别就是bind 会返回一个箭头函数, 因为箭头函数的 this 就是包裹他的外层的this(即要执行的函数),因此可以实现延迟调用。