定义call和apply:函数call()方法被执行,函数里面的this会指向第一个参数值,除了第一个参数值之后的几个分支都是passedintothefunction,简而言之就是在函数运行的时候改变this点。使用示例:fn.call(obj,args1,args2...),fn.apply(obj,[arg1,arg2...]),call和apply除了第二个参数传递方式不同外其他都是一样的。例如1:varobj={name:'Programmer'};functionfn(){console.log(this.name)}fn()//this.name=>undefinedfn.call(obj)//this.name=>'程序员米粉'总结:1、fn函数调用call方法执行时,函数的this指向obj2,执行call方法和fn函数。如果你还不明白,当执行fn.call(obj)时,可以认为是在obj对象中执行了一个fn函数。那么fn函数中的this点就是obj又如2:varobj={name:'程序员米粉',fn:function(){console.log(this.name)}};obj.fn();//this.name=>'程序员米粉'总结:1.当执行例子1中的fn.call(obj)时,相当于例子2的obj.fn();当call方法被调用时,会改变当前调用函数的执行上下文(也就是改变this的指向)。SimulationStep1Example1:varobj={name:'ProgrammerRice'};functionfn(){console.log(this.name)}fn.call(obj)//this.name=>'ProgrammerRice'例子2:varobj={name:'程序员米粉',fn:function(){console.log(this.name)}};obj.fn();//this.name=>'程序员米粉'实现自己的myCall方法,首先观察例1和例2中测得的obj对象的区别,区别:1、例2中obj增加了fn函数方法。2、例2中的执行方式为obj.fn()执行,而例1中的执行方式为fn.call(obj)。这个好办,我们怎么把例1改成例2呢?下面总结一下步骤:1.将fn函数设置为对象的一个??属性2.调用fn函数执行。3.调用完成后,从对象中删除fn属性(函数)。(给对象添加属性,我们调用后删除即可)有了思路,我们可以这样写代码:obj.fn=fn;obj.fn();deleteobj.fn;//按照上面的思路删除属性,然后按照这个思路写自己的myCall方法:Function.prototype.myCall=function(context){context.fn=this;上下文.fn();deletecontext.fn;};varobj={name:'程序员米粉'};functionfn(){console.log(this.name);}fn.myCall(obj)//this.name=>'程序员米粉'````执行myCall方法,可以得出this指向obj对象,并打印期望值,至此该方法第一步完成!#Simulationstep2继续改进myCall方法,更改fn方法,增加2个参数,再次执行该方法。functionfn(index,value){console.log(this.name);console.log(index,value);}fn.myCall(obj,111,'我是一个值');//this.name=>'程序员米粉'//undefined,undefined执行一个fn函数,只打印出一个值,传入参数,不打印出来。那么就需要修改一下方法,让参数也能打印出来。我们可以从arguments对象中获取值,arguments对象代表函数传入的对象,打印出来看看。Function.prototype.myCall=function(context){console.log(arguments);context.fn=this;context.fn();deletecontext.fn;};打印出的arguments对象:我们可以看到arguments对象结构为:{'0':{name:'程序员米粉'},'1':111,'2':'我是一个值'}0代表传入的第一个参数,1代表第二个参数,以此类推。我们看到arguments是一个类数组,所以我们可以使用数组的方法来存储它。由于我们只获取参数,所以我们从1开始取值。varargs=[];for(vari=1;i
