为了更美好的明天而战|

园龄:粉丝:关注:

🔖js
2022-03-11 11:35阅读: 47评论: 0推荐: 0

手写call&apply

参考
来源:https://www.bilibili.com/video/BV1sN411974w?p=2
细讲:https://www.jianshu.com/p/b5d39d2046ae

1. call()

  • call()可以被所有的函数继承,所以 call() 应该被定义在 Function.prototype
  • call()this 绑定到第一个入参指定的对象上,并根据传入的参数执行函数
Function.prototype.myCall = function(context, ...args){
    // 不传第一个参数默认为windows
    context = context || window
    //普通函数的this指向调用者, 故this就是要改造的那个函数
    //将函数挂载到目标对象上
    context.func = this
    //执行函数,并保存返回值
    let res = context.func(...args)
    //删除之前挂载在目标对象上的函数,还原目标对象
    delete context.func
    //return返回值
    return res
}

2. apply()

  • apply()call() 唯一的区别就是前者需要将目标函数的入参逐个传入,后者的入参则以数组形式被传入。
Function.prototype.myApply = function(context, args){
    context = context || window
    context.func = this
    let res = context.func(...args)
    delete context.func
    return res
}

3. bind()

  • bind() 入参方式是逐个传入, 但是 bind() 返回值是一个函数
Function.prototype.myBind = function(context, ...args){
    let _this = this
    return function Fn(){
        //因为返回值是一个函数,需要判断 new Fn() 的情况
        //new 会让 this 指向这个新的对象,所以直接判断 Fn 是否在 this 的原型链上
        if(this instanceof Fn){
               return new _this(...args, ...arguments)
        }
        //调用 call 改变 this 指向
        return _this.call(context, ...args, ...arguments)
    }
}
posted @   沧浪浊兮  阅读(47)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起