函数的方法
每个函数都拥有两个非继承而来的方法:apply()和call()。
这两个方法的用途都是在特定的作用域中调用函数;实际上等于设置函数体内this对象的值。
apply()方法接收两个参数:一个是在其中运行函数的作用域;另一个是参数数组(可以是Array实例,也可以是arguments对象)。
call()方法接收两个参数:一个是在其中运行函数的作用域;另一个是传递给函数的参数(必须逐一列举)。
apply()方法与call()方法的区别仅仅在于接收参数的方式不同。
1 function sum(num1, num2) { 2 return num1 + num2; 3 } 4 function applySum1(num1, num2) { 5 return sum.apply(this, arguments); //传入arguments对象 6 } 7 function applySum2(num1, num2) { 8 return sum.apply(this, [num1, num2]); //传入数组 9 } 10 function callSum(num1, num2) { 11 return sum.call(this, num1, num2); //逐一传入参数 12 } 13 console.log(applySum1(10, 20)); //30 14 console.log(applySum2(10, 20)); //30 15 console.log(callSum(10, 20)); //30
apply()和call()真正强大的地方在于能够扩充函数赖以运行的作用域。
1 window.color = "red"; 2 var o = { 3 color : "green" 4 }; 5 function sayColor() { 6 console.log(this.color); 7 }; 8 sayColor(); //"red" 9 sayColor.call(this); //"red" 10 sayColor.call(window); //"red" 11 sayColor.call(o); //"green"
使用apply()和call()来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。
两个方法都允许显式地指定调用所需的this值,也就是说,任何函数都可以作为任何对象的方法来调用,哪怕这个函数根本不是那个对象的方法。
ECMAScript5中还定义了一个方法:bind();这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
示例:
1 window.color = "red"; 2 var o = { 3 color : "green" 4 }; 5 function sayColor() { 6 console.log(this.color); 7 }; 8 var x = sayColor.bind(o); 9 x(); //"green"
创建一个sayColor函数的新实例x,并将其this对象的值绑定为对象o,所以,this.color === o.color === "green"。