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)));
}
}
}
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持毛票票!