天天看點

JS程式設計建議——59:推薦動态調用函數

建議59:推薦動态調用函數

調用函數更便捷的方式是使用Function對象的call和apply方法。apply與call方法在本質上沒有太大差別,隻不過它們傳遞給函數的參數方式不同, apply是以數組形式進行參數傳遞,而call方法可以同時傳遞多個值。

如果某個函數僅能夠接收多個參數清單,而現在希望把一個數組的所有元素作為參數進行傳遞,那麼使用apply方法就顯得非常便利。

function max(){

}

var a = [23, 45, 2, 46, 62, 45, 56, 63];

var m = max.apply( Object, a );

alert( m ); //63

在上面的示例中,首先定義一個函數來計算所傳遞實參的最大值。由于該函數僅能夠接收多個數值參數,是以通過apply方法動态調用max()函數,然後把它綁定為Object對象的一個方法,并借機把一個數組傳遞給它,最後傳回此函數的運作值。如果沒有apply方法,想使用max()函數來計算數組中最大元素值,就需要把數組的所有元素讀取出來,然後再傳遞給函數,顯然這種做法是費力不讨好的。

實際上,也可以把數組元素通過apply方法傳遞給系統對象Math的max方法來計算數組的最大元素值。

var a = [23, 45, 2, 46, 62, 45, 56, 63]; // 聲明并初始化數組

var m = Math.max.apply( Object, a ); // 調用系統函數max

alert( m ); //63

使用call和apply方法可以把一個函數轉換為方法傳遞給某個對象。這種行為隻是臨時的,函數最終并沒有作為對象的方法而存在,當函數被調用後,該對象方法會自動被登出。下面的示例具體地說明了這種行為。

function f(){}

f.call( Object );

Object.f();

call和apply方法能夠更改對象的内部指針,即改變對象的this指向的内容,這在面向對象的程式設計過程中是非常有用的。

var x = "o";

function a(){

function b(){

function c(){

function f(){

f(); //字元o,即全局變量x的值。this此時指向window對象

f.call( window ); f.call( new a() ); //字元a,即函數a内部的局部變量x的值。this此時指向函數a

f.call( new b() ); //字元b,即函數b内部的局部變量x的值。this此時指向函數b

f.call( c ); /undefined,即函數c内部的局部變量x的值,但是該函數并沒有定義x變量,是以傳回沒有定義。this此時指向函數c/

通過上面示例的比較,能夠很直覺地發現,函數f内部的this關鍵字會随着所綁定的對象不同而指向不同的對象。是以,利用call或apply方法能夠改變函數内部指針指向所綁定的對象,進而實作屬性或方法繼承。

function e(){

e() //字元串a

上面的示例說明,如果在函數體内使用call和apply方法動态調用外部函數,并把call和apply方法的第一個參數值設定為關鍵字this,那麼目前函數e将繼承函數f的所有成員。使用call和apply方法能夠複制調用函數的内部變量給目前函數體,更改了函數f的内部關鍵字this指向函數e,這樣函數e就可以引用函數f的内部成員。

最後,再看一個比較複雜的示例。在這個示例中将示範如何使用apply方法循環更改目前指針,進而實作循環更改函數的結構。

function r( x ){

function f( x ){

function o(){

for( var i = 0 ; i < 10; i ++ ){

執行上面代碼後會看到,提示資訊框中的提示資訊不斷變化。該示例的核心就在于函數o的設計。在這個函數中,首先使用一個臨時變量存儲函數r。然後修改函數r的結構,在修改的函數r的結構中,通過調用apply方法修改原來函數r的指針指向目前對象,同時執行原函數r,并把執行函數f的值傳遞給它,進而實作修改函數r的return語句的後半部分資訊,即為傳回值增加一個字首字元“=”。這樣每次調用函數o時,都會為其增加一個字首字元“=”,進而形成一種動态的變化效果。

當然,call和apply方法的應用是非常靈活的,在大型JavaScript技術架構中經常會用到它們,利用它們可以實作動态更改對象的指針,進而實作各種複雜的功能。

繼續閱讀