這一節是是關於另一個 JavaScript 的關鍵字「參數 (arguments)」,這是在執行一個函式的時候引擎會自動幫我們設定好的關鍵字。雖然在下一版本的 JavaScript 就不會這麼常提到這個關鍵字,而是用 spread
處理 arguments
的工作。但是如果現在去看任何程式碼,尤其是框架和資源庫,還是會在原始碼看到 arguments
變數。所以我們應該要認識及知道它的用處。
已知執行函數的時候,一個執行環境被創造,然後 JavaScript 引擎會幫你設定一些東西,像是變數環境 來包住變數,給範圍鏈的外部環境參考,以及特殊關鍵字 this
(它會依據函數的位置和不同被呼叫的方式,指向不同的東西)。最後它還設定一個特殊關鍵字 arguments
。
arguments
包含所有的值,所有傳入所呼叫的函數的參數 (the parameters you pass into a function) 。其實 arguments
只是另一個傳入函數的參數的名稱而已,但是 JavaScript 用 arguments
統稱所有「傳入函數的參數」。
arguments
要了解 arguments
到底用處是什麼,可以看以下例子
1 |
function greet(firstname, lastname, language) { |
JavaScript 和其它程式語言的差別在於,我可以呼叫 greet
然後不傳入任何參數,而不會報錯。在瀏覽器執行,得到 undefined。在函數執行的時候,發生提昇 (hoisting) 的狀況,它設定好這些東西的初始值,即便我還沒提供確切的特定值。執行函數的地一件事情是設定好 firstname
、lastname
的記憶體空間,然後設定它們為 undefined。
如果傳入參數,它會由左到右處理,如果我只傳入一個 ‘John’,它會假定這是 firstname
然後我沒有傳入其它東西到 lastname
和 language
,出現 undefined 的原因就是因為 hoisting。這表示可以省略傳入參數,或者可以只傳入一部份的參數
1 |
function greet(firstname, lastname, language) { |
![](https://i.imgur.com/INhLkRQ.
雖然這看起來有點奇怪,但其實這是一個強大的概念。例如,在下一版本的 JavaScript ,如果沒有傳入參數值到函數裡面,可以設定預定參數
1 |
function greet(firstname, lastname, language='en') { |
然而,這並非所有瀏覽器都支援,所以可以這樣使用預定參數的概念。亦即如果沒有傳入參數給函式,如果是 undefined 就會使用 ||
運算子,強制型轉成 false,因為 undefine 會強制型轉成 false,最終會得到 en 的值。
1 |
function greet(firstname, lastname, language) { |
![](https://i.imgur.com/iUGjoEh.
現在繼續關注 JavaScript 設定的關鍵字 arguments
,沒有在任何地方宣告,但自動就可以取用。
1 |
function greet(firstname, lastname, language) { |
argument
包含所有傳入參數的值,但因為這是一個特殊的關鍵字,所以那些微微傾斜的中括號,意味它其實是 「像陣列的」(array-like)。這表示它的動作和陣列相似,看起來也很像。但它不是陣列。它只有一部份陣列的功能。
所以如果我不想要我的函式做任何動作,也沒有傳入任何的參數,我可以檢查 argument.length
,長度為 0 表示這個陣列是空的,一個回傳陳述句會將我踢出函式
1 |
function greet(firstname, lastname, language) { |
所以雖然 argument
沒有參數名稱,只有值,我依然可以像陣列一樣使用它,可以用中括號運算子,像是我們可以利用 arguments 來判斷函式有沒有傳入參數,或者取出特定索引的值等等運用。
1 |
function greet(firstname, lastname, language) { |
spread parameter 其餘參數
隨著 JavaScript 的發展,在 ES6 中,我們可以使用其餘參數...
來取代 arguments ,但不代表 arguments 不存在了,它仍然可以使用,只是有更好的選擇。
簡單來說如果我們有傳入函式的參數,可以使用「…」來省略,但要特別注意的是,只能在沒有其他參數下,或者「…」必須是最後一個參數才可以使用。
其餘參數比起 arguments 好用的地方在於,其餘參數是一個真正的陣列,支援所有可以用於陣列上的方法, arguments 是類陣列,處理上較為麻煩。
1 |
function greet(firstname, lastname, language,...other) { |
計算加總 — 其餘參數
1 |
function sum(...input) { |
計算加總 — arguments
1 |
function sum() { |
雖然 arguments 也能做到一樣的事情,但是因為不是真正的陣列,沒辦法使用 ES6 新增的一些好用的陣列方法,所以只能使用 for 迴圈一個個加總,或者使用其他方式將類陣列轉換成真正的陣列。
也因為 arguments 不能自訂一個名稱,所以也很難讓人明白到底這段程式是在做些什麼。
近期评论