我们来先看看call()和apply()的基本用法
每个函数都包含两个非继承而来的方法:apply()和call()。两个方法的用途都是在特定的作用域中调用函数。实际上等于设置this对象的值。首先apply()方法接受两个参数,一个是在其中运行函数的参数,另一个是参数数组。其中,第二个参数可以是array()实例,也可以是arguments对象。例如:
function sum(num1,num2) {
return num1+num2;
}
function callSum1(num1,num2){
return sum.apply(this,arguments);//传入arguments对象
}
function callSum2(num1,num2){
return sum.apply(this,[num1,num2]);//传入数组
}
alert(callSum1(10,10));//20
alert(callSum2(10,10));//20
在上面这个例子中,callSum1()在执行sum()函数时传入了this作为this值(因为在全局作用域中调用的,所以传入的就是windows对象)和arguments对象。而callSum2同样也调用了sum函数,但他传入的则是this和一个参数数组。两者都会正常执行并返回结果。
call()方法和apply()方法的作用相同,他们的区别仅在于接收参数的方式不同。对于call()方法而言,第一个参数是this的值不变,变化的是其余参数都直接传递给函数。也就是在使用call()方法的时候,传递给函数的参数必须一一列举出来
function sum(num1,num2){
return num1+num2;
}
function callSum(num1,num2){
return sum.call(this,num1,num2);
}
alert(callSum(10,10));//20
所以在使用call()方法的情况下,callSum()必须明确地传入每一个参数、结果与使用apply()没有什么不同。如果你打算传入arguments对象。或者包含函数中优先收到的也是一个数组,那么使用apply()/则更方便;否则选择call()更合适。
call()和apply()真正强大的地方是能够扩充函数赖以运行的作用域
window.color = "red";
var o = {color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
在这个例子中。sayColor()也是作为全局函数定义的,而且当在全局作用域中调用它时,它确实会显示“red”,因为this的求值会转换成对window.color的求值。而sayColor(this)和sayColor(window),则是两种显示的在全局区域中调用函数的方式,结果当然会显示red,但,当运行sayColor(o)时,函数的执行环境就不一样了,因为此时函数体内的this对象指向了o,于是结果为blue。
使用call()或apply()来扩充作用于的最大好处,就是对象不需要与方法有任何的耦合关系。
bind()是一个可以将函数绑定到特定环境中的函数,一个简单的bind()函数接受一个函数和一个环境,并返回在给定环境中调用给定函数的函数,并且将所有的参数原封不动的传过去。语法如下:
function bind(fn,conext){
return function(){
return fn.apply(context,arguments);
};
}
这个函数看似简单,但其功能是非常强大的。在bind()中创建一个闭包,闭包使用apply()调用传入的函数,并用apply()传递context对象和参数。注意这里使用的arguments是内部函数的,并非bind的。当返回函数时,他会在给定环境中执行被传入的函数并给出所有参数。bind()函数按如下方式使用:
window.color = "red";
var o = {color:"blue"};
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
只讲了一些基本用法,下次讲实际该怎么选择。