每個(gè)函數(shù)都包含兩個(gè)非繼承而來的方法:apply()和 call()。這兩個(gè)方法的用途都是在特定的作
用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi) this 對(duì)象的值。首先,apply()方法接收兩個(gè)參數(shù):一個(gè)
是在其中運(yùn)行函數(shù)的作用域,另一個(gè)是參數(shù)數(shù)組。其中,第二個(gè)參數(shù)可以是 Array 的實(shí)例,也可以是
arguments 對(duì)象.
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments); // 傳入 arguments 對(duì)象
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]); // 傳入數(shù)組
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20
在上面這個(gè)例子中,callSum1()在執(zhí)行 sum()函數(shù)時(shí)傳入了 this 作為 this 值(因?yàn)槭窃谌?br>
作用域中調(diào)用的,所以傳入的就是 window 對(duì)象)和 arguments 對(duì)象。而 callSum2 同樣也調(diào)用了
sum()函數(shù),但它傳入的則是 this 和一個(gè)參數(shù)數(shù)組.
call()方法與 apply()方法的作用相同,它們的區(qū)別僅在于接收參數(shù)的方式不同。對(duì)于 call()方法而言,第一個(gè)參數(shù)是 this 值沒有變化,變化的是其余參數(shù)都直接傳遞給函數(shù)。換句話說,在使用call()方法時(shí),傳遞給函數(shù)的參數(shù)必須逐個(gè)列舉出來,如下面的例子所示。
function sum(num1, num2){
return num1 + num2;
}
function callSum(num1, num2){
return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20
在使用 call()方法的情況下,callSum()必須明確地傳入每一個(gè)參數(shù)。結(jié)果與使用 apply()沒有什么不同。至于是使用 apply()還是 call(),完全取決于你采取哪種給函數(shù)傳遞參數(shù)的方式最方便。如果你打算直接傳入 arguments 對(duì)象,或者包含函數(shù)中先接收到的也是一個(gè)數(shù)組,那么使用apply()肯定方便;否則,選擇 call()可能更合適。(在不給函數(shù)傳遞參數(shù)的情況下,使用哪個(gè)方法都無所謂。)事實(shí)上,傳遞參數(shù)并非 apply()和 call()真正的用武之地;它們真正強(qiáng)大的地方是能夠擴(kuò)充函數(shù)賴以運(yùn)行的作用域。下面來看一個(gè)例子。
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
這個(gè)例子是在前面說明 this 對(duì)象的示例基礎(chǔ)上修改而成的。這一次,sayColor()也是作為全局函數(shù)定義的,而且當(dāng)在全局作用域中調(diào)用它時(shí),它確實(shí)會(huì)顯示"red"——因?yàn)閷?duì) this.color 的求值會(huì)轉(zhuǎn)換成對(duì) window.color 的求值。而 sayColor.call(this)和 sayColor.call(window),則是兩種顯式地在全局作用域中調(diào)用函數(shù)的方式,結(jié)果當(dāng)然都會(huì)顯示"red"。但是,當(dāng)運(yùn)行 sayColor.call(o)時(shí),函數(shù)的執(zhí)行環(huán)境就不一樣了,因?yàn)榇藭r(shí)函數(shù)體內(nèi)的 this 對(duì)象指向了 o,于是結(jié)果顯示的是"blue"。使用 call()(或 apply())來擴(kuò)充作用域的最大好處,就是對(duì)象不需要與方法有任何耦合關(guān)系。在前面例子的第一個(gè)版本中,我們是先將 sayColor()函數(shù)放到了對(duì)象 o 中,然后再通過 o 來調(diào)用它的;而在這里寫的例子中,就不需要先前那個(gè)多余的步驟了。ECMAScript 5 還定義了一個(gè)方法:bind()。這個(gè)方法會(huì)創(chuàng)建一個(gè)函數(shù)的實(shí)例,其 this 值會(huì)被綁定到傳給 bind()函數(shù)的值。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();