call、bind和apply是Function原型上的方法。它们用于将this的指向更改为自定义函数。js中的调用、绑定、应用都是用c++代码实现的。我们这里用js代码做一个pattern,没有把所有的Boundary条件都考虑进去,只做一个简单的实现。这三个函数在使用时有几点需要注意。定义时需要考虑这些情况。当传入的值是基本数据类型时,调用、apply、bind方法会将其转换成引用数据类型,比如传入的字符串变成String类型,这种转换可以通过Object()来完成。当需要改变的this点没有传递时,函数的this指向window(非严格模式)当传递的this点为null或undefined时,函数的this指向window(非严格模式)严格模式)调用函数的实现定义需要注意第一个参数接收改变了这一点,从第二个参数开始接收函数执行所需参数的实现代码如下Function.prototype.iCall=function(thisArg,...args){//1.获取执行函数varfn=this//2.将函数绑定到传入的对象UpperthisArg=thisArg||thisArg.toString()?Object(thisArg):windowthisArg.fn=fnvarresult=thisArg.fn(...args)//3.删除传入对象的fn函数deletethisArg.fn//4.返回结果returnresult}functionfoo(...args){console.log('绑定的this是:',this)console.log('传递的参数是:',args)}varuser={name:'alice'}//改变foo函数的this指向user,并传递参数1,2,3foo.iCall(user,1,2,3)执行结果为apply的实现定义的apply函数,要注意第一个参数接收改变了this指针,第二个参数接收一个由函数执行所需的参数组成的[数组]。实现代码如下Function.prototype.iApply=function(thisArg,args){//1.获取执行函数varfn=this//2.将函数绑定到传入的对象上thisArg=thisArg||thisArg.toString()?对象(thisArg):窗口thisArg。fn=fnvarresult=thisArg.fn(...args)//3.删除传入对象的fn函数deletethisArg.fn//4.返回结果returnresult}functionfoo(...args){console.log('绑定的this是:',this)console.log('传递的参数是:',args)}varstr="hellojs"vararr=['a','b','c']foo.iApply(str,arr)的执行结果如下bind的实现定义bind函数需要注意第一个参数接收变化后的this指针,第二个参数接收函数执行所需的参数.bind函数不会立即调用该函数,而是返回一个新函数,新函数仍然可以继续传递参数Function.prototype.iBind=function(thisArg,...args){//1.获取执行函数varfn=this//2.将函数绑定到传入的对象上thisArg=thisArg||thisArg.toString()?Object(thisArg):windowthisArg.fn=fnreturnfunction(...params){//3.获取函数执行的结果varresult=thisArg.fn(...args,...params)//4.删除传入对象的fn函数deletethisArg.fn//5.返回结果returnresult}}functionfoo(...args){console.log('boundThespecifiedthisis:',this)console.log('传递的参数是:',args)}varnum=0varfn=foo.iBind(num,20,40)fn(30,50)执行结果如下以上是call、bind、apply的实现方法。代码量不多,但是需要用到这个指向我比较了解,关于这个指向你也可以看看我其他的博文~
