call()和apply()这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this的指向。
首先apply()方法接收两个参数:第一个参数是在其中运行函数的作用域,也就是说第一个参数指出了函数要在哪执行,第二个参数是参数数组或arrgument对象。
1 function sum(num1,num2){ 2 return num1+num2; 3 } 4 function callSum1(num1,num2){ 5 return sum.apply(this,arguments); 6 } 7 function callSum2(num1,num2){ 8 return sum.apply(this,[num1,num2]); 9 } 10 alert(callSum1(10,20)); 11 alert(callSum2(10,20));
上面代码中apply()方法相当于把sum()方法绑定到callSum()中来执行。apply()方法的第二个参数既可以是arguments对象也可以是参数数组。
call()方法与apply()方法的作用相同,区别仅在于接收参数的方式不同,call()方法第一个参数是this值,第二个参数是将原绑定函数的参数逐个列举出来。
1 function sum(num1,num2){ 2 return num1+num2; 3 } 4 function callSum1(num1,num2){ 5 return sum.call(this,num1,num2); 6 } 7 alert(callSum2(10,20));
可以看出,call()和apply()的区别仅在于第二个参数不同。
事实上,call()和apply()的真正强大之处在于能够扩充函数的作用域。
1 window.color='red'; 2 var o={color:'blue'}; 3 function sayColor(){ 4 alert(this.color); 5 } 6 sayColor(); //全局环境下执行,this指向window 7 sayColor.call(this); //此处的this说明函数要在全局下执行,因此this指向window 8 sayColor.call(window); //此处call()方法第一个参数表明sayColor()被绑定到全局下 9 sayColor.call(o); //此处call()方法第一个参数表明sayColor()被绑定到o对象下
如果要划分作用域的话,可以划分为:
上面说了call()和apply()方法,下面讲讲bind()方法
相同点:三者都是用来改变函数体内this的指向,第一个参数都是this要指向的对象
不同点:bind是返回对应函数,方便后面调用;call、apply则是立即调用
1 var bar=function(){ 2 console.log(this.x); 3 } 4 var foo={ 5 x:3 6 } 7 bar(); 8 bar.bind(foo)(); 9 /*或*/ 10 var func=bar.bind(foo); 11 func();
结果为undefined,3。