JS原生实现bind、call、apply的方法整理
我们先来实现bind,实现每个功能之前,肯定要先看下他们的api,到底是怎么调用的,知道怎么调用才能实现。
bind除了可用来绑定this外,还可以绑定默认的参数,如下示例。
function test(arg1,arg2) { console.log(this.a ) console.log(arg1) console.log(arg2) } let obj = { a:'a' } test.bind(obj,'b')('c') //a //b //c
通过观察我们发现就可以找到实现的思路:
每个函数都可以调用bind,所以肯定要把bind方法放到Function.protorype上
bind返回的是个函数
bind可以接收默认参数,我们要保持这个默认参数,然后再返回的函数将默认参数和后传参数合并
可以基于函数的apply功能来更改this并接收合并后参数
function test(arg1,arg2) { console.log(this.a ) console.log(arg1) console.log(arg2) } let obj = { a:'a' } Function.prototype.myBind = function (context) { const self = this const args = [...arguments].slice(1) //接收除context之外的参数,也就是绑定的默认参数 return function () { let all_args = args.concat([...arguments]) //将默认参数和调用参数合并 let result = self.apply(context,all_args) //借助apply来执行 return result } } test.myBind(obj,'b')('c') //a //b //c
上面我们基于apply实现了bind方法,现在再原生实现apply,同样的我们看看怎么使用apply。
apply接收的第一个参数为要替换this的对象,第二个参数是个数组
function test(arg1,arg2) { console.log(this.a ) console.log(arg1) console.log(arg2) } let obj = { a:'a' } test.apply(obj,['b','c'])
我们先来分析一下:
首先肯定是要给 Function.prototype添加一个apply方法
apply接收两个参数,第一个是上下文,第二个是个数组
apply是立即执行的,不像bind返回个函数
重点是怎么修改this呢,这个可以借助this相关的知识点:谁调用某个函数,函数中的this就指向谁
Function.prototype.myApply = function (context = window,args=[]) { const self = this context.fn = self //给上下文添加一个fn属性指向调用myApply的函数,后续执行context.fn(),则fn中的this就指向了context,达到替换this的目的 let result = context.fn(...args) delete context.fn //得到结果之后记得再把fn从context中删除,要不就导致context变化了,这不符合apply的功能 return result }
类似的,我们也可以实现call的功能,call和apply的区别就是传的参数不同,可以用...args来接收call中的其他参数,后面实现就和apply相同了
Function.prototype.myCall = function (context = window,...args) { const self = this context.fn = self let result = context.fn(...args) delete context.fn return result }
点赞(1)