[前端攻坚]:详解call、apply、bind的实现


theme: smartblue
highlight: foundation

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

call apply bind 的实现的面试中几乎必定出现的一些内容,今天来用一篇文章整理一下这里的内容,加深一下JS基础知识体系。同时文章也被收录到我的《JS基础》专栏中,欢迎大家点击收藏加关注。

call的实现

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

let obj = {name:'plus'}
function getName(a){
    console.log(this.name+'_'+a)
}
getName.call(obj,'666') //plus_666

以上的call可以换成用函数的隐式绑定调用的方法来使用 比如

let obj = {
    name:'plus',
    getName: function(a){
        console.log(this.name+'_'+a)
    }
}
obj.getName('666') //plus_666

把函数放到要指向的对象中,通过obj.的隐式调用,就能够改变this的指向

那么根据这个调用方法我们就有思路来实现我们的call方法了

手写call

  • 1.在对象中声明一个临时函数,将要执行的函数放到其中
  • 2.通过隐式调用
  • 3.删除临时函数
  • 4.判断传入对象是否为空

_call(fn,...arg) = function(){
     if(obj===null||obj===undefined){ //没有指定对象时候
         obj =  window
     }
    obj.temp = fn //临时函数
    let res = obj.temp(...arg)
    delete obj.temp //临时函数完成它的任务就要消失了
    return res
}

//改进版
Function.prototype._call = function(obj,...arg){
    obj = obj || window //没有指定对象时候 指向window
    const temp = Symbol() //小技巧,Symbol可以用来声明一个对象的属性
    obj.temp = this //因为call的声明方法是`Function.prototype._call`所以this就是要调用的函数
    let res = obj.temp(...arg)
    delete obj.temp
    return res
}

手写apply

apply的实现基本是和call是差不多的,有区别的一点是对于传入的参数,call接收的是多个参数,apply接收的是一个参数数组


- Function.prototype.apply = function(obj,...arg){
+ Function.prototype.apply = function(obj,arg){
    obj = obj || window //没有指定对象时候 指向window
    const temp = Symbol() //小技巧,Symbol可以用来声明一个对象的属性
    obj.temp = this //因为call的声明方法是`Function.prototype._call`所以this就是要调用的函数
    let res = obj.temp(...arg)
    delete obj.temp
    return res
}

手写bind

bind的实现与call和apply的有点不同,bing中返回的是一个函数,需要对函数进行第二次调用才能真正的执行到函数。我们先来看一下例子。

function getName(a,b,c,d){
    console.log(`${a} ${b} ${c} ${d}`)
}
let obj = {}
let b1 = getName.bind(obj,1,2)
b1(3,4)

我们可以看到bind的最终调用是分两次实现的,这个实现类似于是柯里化的实现,那么看了bin的使用后我们就可以来手动写出bind了

步骤分为几步:

  • 函数中返回一个函数
  • 还是和call、apply函数一样设置一个临时函数
  • 在返回的函数中,因为是最后一次执行,将所有参数传入,比如arg1传入的是1、2,arg2传入的是3、4。
Function.prototype._bind = function (obj,...arg1) {
    obj = obj || window
    const temp = Symbol()
    obj[temp] = this
    return function(...arg2){
        obj[temp](...arg1,...arg2) //obj[temp](1,2,3,4)
    }
}
© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容