想要真正了解一个事物,最好方法就是自己动手实现一个,今天通过自己实现一个 call 和 apply 给大家介绍如何理解和使用 call 和 apply 来调用函数。
consttut={title:"machinelearning"};functiongetTitle(){console.log(`title:${this.title}`)}getTitle.call(tut);
定义一个对象 tut
然后在定义个函数 getTitle
,直接执行getTitle()
函数,this
是指向 window
。用 call
调用函数 getTitle
就会将 this
绑定到 tut
对象上。 所以输出时候就可以用上对象属性 title
。
要了解 call 我们就来创建一个 call
要理解 call 方法如何使用,以及其背后到底发生了什么,最好方法就是自己去实现一个 call 方法。
consttut={title:"machinelearning"}functiondescription(){console.log(`title:${this.title}`)}Function.prototype.newCall=function(obj){console.log(this);}description.newCall(tut);
index.js:10ƒdescription(){console.log(`title:${this.title}`)}
因为这是还没有将 tut
绑定到 this
,所以这时this
现在还是 description
函数本身。
Function.prototype.newCall=function(obj){obj.tmp=this;obj.tmp();//console.log(this);deleteobj.tmp;}
functiondescription(subTitle,summay,type){console.log(`title:${this.title}`);console.log(subTitle,summay,type);//undefinedundefinedundefined}...description.newCall(tut,'machinelearning','summary','video');
consttut={title:"machinelearning"}functiondescription(subTitle,summay,type){console.log(`title:${this.title}`)console.log(subTitle,summay,type);}Function.prototype.newCall=function(obj){varobj=obj||windowobj.tmp=this;varnewArguments=[];for(leti=1;i<arguments.length;i++){newArguments.push('arguments['+i+']');}console.log(newArguments)eval('obj.tmp('+newArguments+')');//console.log(this);deleteobj.tmp;}description.newCall(null,'machinelearning','summary','video');
consttut={title:"machinelearning"}functiondescription(subTitle,summay,type){//console.log(`title:${this.title}`)//console.log(subTitle,summay,type);return{title:this.title,subTitle:subTitle,summay:summay,type:type}}Function.prototype.newCall=function(obj){varobj=obj||windowobj.tmp=this;varnewArguments=[];for(leti=1;i<arguments.length;i++){newArguments.push('arguments['+i+']');}console.log(newArguments)constresult=eval('obj.tmp('+newArguments+')');//console.log(this);deleteobj.tmp;returnresult;}constres=description.newCall(tut,'machinelearning','summary','video');console.log(res)//{title:'machinelearning',subTitle:'machinelearning',summay:'summary',type:'video'}
aplly 的实现
apply 方法与 call 比较类似,第一个参数是调用方法的对象,第二个参数是参数数组,apply 实现了 call 比较类似,我先把代码呈现在这里,大家应该一看就懂。
consttut={title:"machinelearning"}functiondescription(subTitle,summay,type){console.log(`title:${this.title}`)console.log(subTitle,summay,type);//return{//title:this.title,//subTitle:subTitle,//summay:summay,//type:type//}}Function.prototype.newApply=function(obj,arr){varobj=obj||windowobj.tmp=this;if(!arr){obj.tmp()}else{varnewArguments=[];for(leti=0;i<arr.length;i++){newArguments.push('arr['+i+']');}constresult=eval('obj.tmp('+newArguments+')');}deleteobj.tmp;}description.newApply(tut,['machinelearning','summary','video']);