问题
- 这三个干什么用的?
- 怎么实现他们?
- 有哪些疑点剖析?
解答
- 这三个干什么用的 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会返回一个函数,可以执行的。
- 怎么实现他们?
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.有哪些疑点剖析?
- 为什么要Function.prototype.mycall
因为这三个方法都是function才能调用,你没见过obj.call,都是obj.func.call(),所以可以直接挂在Function的原型上面
- 为什么要symbol,然后给传进来的obj做key
因为需要确保不要覆盖掉传进来的obj上的key
- 为什么ob[symbol] = this
首先解释ob[symbol],这个是为什么要用call,apply,bind的原因,传进来的obj也得有这个方法才能调用,不然会报错找不到这个方法,这样写也是为了让func内的this指向ob
为什么= this,因为test.do.mycall(test2),这个时候的this是test.do,就是函数本身
- 为什么 delete ob[symbol]
只是借用一下传入的obj,赋值后删除不影响obj
- 为什么 return res
函数执行完了值也要返回
实践
const test = {name:'zyc',do(){console.log(this.name)}}
const test2 = {name:'ymy'}
test.do.mycall(test2) // 输出ymy