JavaScript 中 apply 、call 的详解
apply和call的区别
ECMAScript规范给所有函数都定义了call与apply两个方法,它们的应用非常广泛,它们的作用也是一模一样,只是传参的形式有区别而已。
apply()
apply方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。
varobj={ name:'linxin' } functionfunc(firstName,lastName){ console.log(firstName+''+this.name+''+lastName); } func.apply(obj,['A','B']);//AlinxinB
可以看到,obj是作为函数上下文的对象,函数func中this指向了obj这个对象。参数A和B是放在数组中传入func函数,分别对应func参数的列表元素。
call()
call方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。
varobj={ name:'linxin' } functionfunc(firstName,lastName){ console.log(firstName+''+this.name+''+lastName); } func.call(obj,'C','D');//ClinxinD
对比apply我们可以看到区别,C和D是作为单独的参数传给func函数,而不是放到数组中。
对于什么时候该用什么方法,其实不用纠结。如果你的参数本来就存在一个数组中,那自然就用apply,如果参数比较散乱相互之间没什么关联,就用call。
apply和call的用法
1.改变this指向
varobj={ name:'linxin' } functionfunc(){ console.log(this.name); } func.call(obj);//linxin
我们知道,call方法的第一个参数是作为函数上下文的对象,这里把obj作为参数传给了func,此时函数里的this便指向了obj对象。此处func函数里其实相当于
functionfunc(){ console.log(obj.name); }
2.借用别的对象的方法
先看例子
varPerson1=function(){ this.name='linxin'; } varPerson2=function(){ this.getname=function(){ console.log(this.name); } Person1.call(this); } varperson=newPerson2(); person.getname();//linxin
从上面我们看到,Person2实例化出来的对象person通过getname方法拿到了Person1中的name。因为在Person2中,Person1.call(this)的作用就是使用Person1对象代替this对象,那么Person2就有了Person1中的所有属性和方法了,相当于Person2继承了Person1的属性和方法。
3.调用函数
apply、call方法都会使函数立即执行,因此它们也可以用来调用函数。
functionfunc(){ console.log('linxin'); } func.call();//linxin
call和bind的区别
在EcmaScript5中扩展了叫bind的方法,在低版本的IE中不兼容。它和call很相似,接受的参数有两部分,第一个参数是是作为函数上下文的对象,第二部分参数是个列表,可以接受多个参数。
它们之间的区别有以下两点。
1.bind发返回值是函数
varobj={ name:'linxin' } functionfunc(){ console.log(this.name); } varfunc1=func.bind(obj); func1();//linxin
bind方法不会立即执行,而是返回一个改变了上下文this后的函数。而原函数func中的this并没有被改变,依旧指向全局对象window。
2.参数的使用
functionfunc(a,b,c){ console.log(a,b,c); } varfunc1=func.bind(null,'linxin'); func('A','B','C');//ABC func1('A','B','C');//linxinAB func1('B','C');//linxinBC func.call(null,'linxin');//linxinundefinedundefined
call是把第二个及以后的参数作为func方法的实参传进去,而func1方法的实参实则是在bind中参数的基础上再往后排。
在低版本浏览器没有bind方法,我们也可以自己实现一个。
if(!Function.prototype.bind){ Function.prototype.bind=function(){ varself=this,//保存原函数 context=[].shift.call(arguments),//保存需要绑定的this上下文 args=[].slice.call(arguments);//剩余的参数转为数组 returnfunction(){//返回一个新函数 self.apply(context,[].concat.call(args,[].slice.call(arguments))); } } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!