定义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个参数,再次执行该方法。//想想怎么给fn函数传参数执行context.fn(arguments[1],arguments[2]);可能有人会想到下面的方法://通过join方法将数组中的元素传入函数中参数context.fn(args.join(','))//这种情况下执行context.fn(args.join(','))变成:context.fn("arguments[1]","arguments[2]");//变成字符串,变成死值,不管传什么,它将变成一个字符串"arguments[1]","arguments[2]"。...可能有人会想到用ES6的方式来解决。这个调用是ES3的方法,所以还是用ES6的方法解决不了。其实我们可以使用eval方法来解决。查看文档可知eval()函数会将传入的字符串作为JavaScript代码执行。这到底是什么意思?eval()的参数是一个字符串。如果字符串表示一个表达式,则eval()计算该表达式。如果参数表示一个或多个JavaScript语句,则eval()会执行这些语句。例如:console.log(eval('2+2'));//2+2=>4,最终输出为2console.log(eval('context.fn('+args+')'))//相当于运行context.fn(arguments[1],arguments[2],...),使用eval执行一串JavaScript语句。+[eval更详细链接;](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval)args会自动调用Array.toString()方法。通过eval自动执行就变成了context.fn(arguments[1],arguments[2])这样执行。代码如下:varobj={name:'程序员米饭'};函数fn(index,value){console.log(this.name);//程序员米饭console.log(index,value);//111i是一个值}Function.prototype.myCall=function(context){context.fn=this;变量参数=[];对于(vari=1;i
