在Java中,很多人都應該有同名函式,不同函式簽名的多載Overload概念,但是在JavaScript中,是不能把這樣的觀念一併套用的。
我們來看一下以下的程式碼:
<html> <body> <script type="text/javascript"> function foo(a) { alert('foo(a) is called!'); } function foo(a,b,c) { alert('foo(a,b,c) is called!'); } foo('a'); </script> </body> </html>如果有寫過Java但不熟JavaScript的話,很容易就會想說跳出的視窗應該是 "foo(a) is called!" 的吧,不過事實上並不是這樣的。
事實上跳出的事窗會是 "foo(a,b,c) is called!",也就是說 foo(a) 這個function跟本就沒被呼叫到,很顯然的,JavaScript並不會因為不同的方法簽名呼叫就使用不同方法簽名的方法,也就是沒有Java常見的多載(overload)特性。
其實在JavaScript中,函式的名稱只是一個類似指標(C語言)或參考(Java的reference)的查西,在每一次指定function內容及名稱時,名稱指向的位置都會改變,上述的例子中,第一次foo指向一個function及記憶體位置,而第二次又指向了另外一個function內容及記憶體位置,所以foo(a)就沒用了,最後foo代表的就是foo(a,b,c)。
在JavaScript中,呼叫方法function)時,輸入的參數是以類似陣列的方式傳進方法中的,所以其實方法簽明中的輸入參數個數並不是很重要,甚至可以傳入參數給方法簽名沒有輸入參數的方法(當然在方法簽名上標名變數名稱有利於程式易讀性及使用)。
如以下的程式碼是完全可以成功且正確的執行的:
<html> <body> <script type="text/javascript"> function sum() { var inputArguments = sum.arguments; var answer = 0; for (i=0 ; i < inputArguments.length ; i++){ answer = answer + inputArguments[i]; } alert('輸入了' + inputArguments.length + '個數字,' + '總合為:' + answer); } sum(1); sum(1,2); sum(1,2,3); </script> </body> </html>
執行後將可以看到三個視窗跳出來,分別顯示如下文字:
輸入了1個數字,總合為:1
輸入了2個數字,總合為:3
輸入了3個數字,總合為:6
可以發現,在JavaScript中,方法本身其實就像是一個物件,例如在上例中 sum() 本身就像是一個物件,可以用sum.arguments來存取輸入的參數,而輸入的參數也是像一個物件,可以存取其length及各元素的值。
而也因為 sum 就代表名為 sum 的方法,所以如果我們用方法的名稱去宣告一個新變數是會發生問題的,例如像下面這個例子,就會發生 TypeError: Cannot read property 'arguments' of undefined 的錯誤 ,因為此時sum()代表呼叫sum函式,而使用了 var sum=0 時,sum.arguments.length的sum變成指向一個sum()中的sum屬性了,所以是還沒defined的(這時真正執行的順序是var sum; --> alert(sum.arguments.length); --> alert(sum); 請參考 "Javascript的變量聲明提昇"):
<html> <body> <script type="text/javascript"> function sum() { try{ alert(sum.arguments.length); //這裡的sum是指sum()中的sum屬性,但因沒有定義而會出錯 var sum = 0; alert(sum); }catch(error){ alert(error); } } sum(1,2); //加括號時,sum指的是名為sum的function </script> </body> </html>
那正確的寫法是什麼呢?事實上argument這個屬性是可以直接在function裡使用而不用在前面特別指定function名稱的,所以這樣寫就不會報錯了:
<html> <body> <script type="text/javascript"> function sum() { try{ alert(arguments.length); var sum = 0; alert(sum); }catch(error){ alert(error); } } sum(1,2); //輸出為: //2 //0 </script> </body> </html>
如果這樣的話,也就是沒有下var sum=0,即沒有跟sum()的名稱衝突的話,也是可以的,此時sum就是function了
<html> <body> <script type="text/javascript"> function sum() { try{ alert(arguments.length); var sum2 = 0; alert(sum); }catch(error){ alert(error); } } sum(1,2); //輸出為: //2 //function sum() { // try{ // alert(arguments.length); // //alert(typeof(sum)); // var sum2 = 0; // alert(sum); // }catch(error){ // alert(error); // } //} </script> </body> </html>
參考資料:
沒有留言 :
張貼留言