50行代码手写call,apply,bind方法

本文是对该文章的自己一些理解,附带实例。跟大家分享一下
https://segmentfault.com/a/1190000020044435
call方法实现:

Function.prototype.mycall = function(context,...arg){   // Function是所有函数对象的构造函数。这里给Function的原型声明了一个mycall方法,则所有的函数都拥有了这个mycall方法
    const temp = Symbol("unique symbol")  // symbol代表标识唯一性的ID(就算每次参数是unique symbol,但是temp都不相等)
    context[temp] = this   // 这里的this 代表调用mycall的函数。this的指向:被谁调用,this就指向谁。这里的context就是传递的obj2。可以理解为obj2.fn = obj1.fn
    context[temp](...arg)  // 这里通过展开运算符传递参数。展开运算符是传递参数的一种简写。调用fn函数
    delete context[temp]  // 这时将obj2.fn删除。一定要删除,因为obj2本身是没有这个函数的,只是在传递作用域调用时,做一个临时属性
}

let obj1 = {
    name: "obj1",
    fn: function(a,b,c){
        console.log(this.name+": "+ a + b + c)
    }
}
let obj2 = {
    name: "obj2",
}
obj1.fn.mycall(obj2,4,5,6)

apply方法实现:

Function.prototype.myApply = function (context, arg) { // apply和call实际上只有参数传递上的区别,传递的第二个参数是一个数组
    const fn = Symbol('临时属性')
    context[fn] = this
    context[fn](...arg)
    delete context[fn]
}

let obj1 = {
    name: "obj1",
    fn: function(a,b,c){
        console.log(this.name+": "+ a + b + c)
    }
}
let obj2 = {
    name: "obj2",
}
obj1.fn.myApply(obj2,[1,2,3])

bind方法实现:

Function.prototype.myBind = function (context, ...firstarg) {
    const that = this // 当前调用myBind的函数            
    const bindFn = function (...secoundarg) {   // bind的本质是将call方法封装成函数return 执行这个函数则调用call方法
        return that.mycall(context, ...firstarg, ...secoundarg) // 调用bind的时候可能传一次参,调用bind返回的函数可能会再一次传参。
   }
    bindFn.prototype = Object.create(that.prototype) //  复制源函数的prototype给fToBind
    return bindFn
}
let obj1 = {
    name: "obj1",
    fn: function (...arg) {
        console.log(this.name + ": " + arg)
    }
}
let obj2 = {
    name: "obj2",
}
let fnAfterBind = obj1.fn.myBind(obj2, 1, 2, 3)
fnAfterBind(4, 5, 6)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值