js call,apply,bind

126 阅读2分钟

问题

  1. 这三个干什么用的?
  2. 怎么实现他们?
  3. 有哪些疑点剖析?

解答

  1. 这三个干什么用的 call,apply都是用在函数上的,用来借方法给其他obj用的,比如
const test = {name:'zyc',do(){console.log(this.name)}}
const test2 = {name:'ymy'} //test2没有do方法,找test借
test.do.call(test2) // 输出ymy

call,和apply的区别仅在于入参的区别,call是arg1,arg2...这种入参,apply是[arg1,arg2]这种方式

bind入参也是arg1,arg2...这种方式,但是bind会返回一个函数,可以执行的。

  1. 怎么实现他们?
Function.prototype.mycall = function(obj, ...arg){
    const ob = obj || window
    const symbol = Symbol()
    ob[symbol] = this
    console.log(this,ob)
    const res = ob[symbol](...arg)
    delete ob[symbol]
    return res
    
}

Function.prototype.myapply = function(obj, arg){
    const ob = obj || window
    const symbol = Symbol()
    ob[symbol] = this
    const res = ob[symbol](...arg)
    delete ob[symbol]
    return res
    
}

Function.prototype.mybind = function(obj, ...arg){
    const ob = obj || {}
    const symbol = Symbol()
    ob[symbol] = this
    return function(...afterarg){
        const res = ob[symbol](...arg,...afterarg)
    delete ob[symbol]
    return res
    }
}

const test = {name:'zyc',do(){console.log(this.name)}}
const test2 = {name:'ymy'}
test.do.mycall(test2)

3.有哪些疑点剖析?

  1. 为什么要Function.prototype.mycall

因为这三个方法都是function才能调用,你没见过obj.call,都是obj.func.call(),所以可以直接挂在Function的原型上面

  1. 为什么要symbol,然后给传进来的obj做key

因为需要确保不要覆盖掉传进来的obj上的key

  1. 为什么ob[symbol] = this

首先解释ob[symbol],这个是为什么要用call,apply,bind的原因,传进来的obj也得有这个方法才能调用,不然会报错找不到这个方法,这样写也是为了让func内的this指向ob

为什么= this,因为test.do.mycall(test2),这个时候的this是test.do,就是函数本身

  1. 为什么 delete ob[symbol]

只是借用一下传入的obj,赋值后删除不影响obj

  1. 为什么 return res

函数执行完了值也要返回

实践

const test = {name:'zyc',do(){console.log(this.name)}}
const test2 = {name:'ymy'}
test.do.mycall(test2) // 输出ymy