# 筆記_重新認識JS:Day17函式裡的「參數」\(下)_函式裡的參數 ---- ###### tags: `javascript` Javascrip 是弱型別語言 不像C# 如果傳入function中參數的數量或型別錯誤就會error 函式的參數 之前我們說過,當我們呼叫一個函式的時候,可以透過「函式名稱」加上「小括號」的方式呼叫。 而小括號內的資料,就是「參數」。 ```javascript= var plus = function (numA, numB) { return numA + numB; }; plus(1, 2); // 3 plus(3, 4); // 7 ``` 像上面這樣,呼叫 `plus(1, 2)` ,其中的 1, 2 作為參數傳至 plus 這個 function,這時 numA 與 numB 內的值就會分別是 1 與 2。 於是,回傳的內容 `numA + numB` 自然就會是 1 + 2 的結果了。 然而,即便我們定義函式時有指定「參數的數量」(如上面範例,分別為 numA 與 numB),但是在呼叫的時候,並不會針對代入的參數數量做檢查。 也就是說,呼叫 `plus` 你可以寫成: ```javascript= plus(1, 2, 3, 4, 5); ``` 或是 ```javascript= plus( ); ``` 在 JavaScript 都是合法的,只不過在沒有傳入值作為參數的情況下,那些沒有指定的參數預設會是 undefined。 而多傳入的那些參數,在「大部分」情況下是沒有意義的。 既然我說了「大部分」那就代表還是可以拿得到的。 ## arguments 物件 事實上,當函式被呼叫的時候,會產生一個 `arguments` 物件。 而這個 `arguments` 物件的內容,其實就是我們呼叫函式所代入的「參數」。 以剛剛的 plus 作為範例: ```javascript= plus(1, 2, 3, 4, 5); ``` 很明顯我們代入的參數數量超過了先前定義好的參數數量,那麼多餘的 3, 4, 5 我們有辦法可以取得嗎? 可以,就透過 arguments 這個物件。 ```javascript= var plus = function (numA, numB) { console.log( arguments.length ); return numA + numB; }; // 因為有 5 個參數,會先 log 出 5,然後回傳 1+2 的結果 plus(1, 2, 3, 4, 5); ``` 請注意, `arguments` 雖然看起來像個「陣列」,但實際上他只是個帶有「索引」特性的物件,然後內建個 `length` 屬性,其他地方與「陣列」完全不同,當然也沒有 ``.map()`` 或 ``.filter()`` 這些陣列才有的方法。 [註1] 所以說,即便在定義函式的時候完全沒有指定參數給它,我們仍然可以在函式內透過 `arguments` 來取得參數。 ```javascript= var plus = function (numA, numB) { for( var i = 0; i < arguments.length; i++ ){ console.log( arguments[i] ); } return numA + numB; }; // console.log 印出 1 2 3 4 5 plus(1, 2, 3, 4, 5); ``` 除此之外, `arguments` 物件還有另一個屬性: `callee`,指的是目前執行的函式。 ```javascript= var plus = function (numA, numB) { // arguments.callee 指的是 plus 這個 function console.log( arguments.callee ); return numA + numB; }; ``` 當我們需要在函式執行「遞迴」 (在函式內自我呼叫) 時,可以執行 `arguments.callee()`來達成,這屬性在「匿名函式」時特別有用。 但要小心的是,在「嚴格模式」下不允許存取 `arguments.caller` 和 `arguments.callee` 這兩個屬性。 另外, ES6 的箭頭函式 (Arrow Function) 也沒有提供 arguments 物件。 ## 以「物件」作為參數 ## 參數的預設檢查