[JS奇怪的世界]No.31 arguments與spread(其餘參數)

前言

這邊將要來講 JavaScript 中另一個特別的關鍵字,在我們執行函數時就自動設定好的一個關鍵字 arguments 及 ES6 的 spread 又稱其餘參數。

arguments

在執行環境被建立時 JavaScript 會替我們設定一些東西像是變數環境來包住我們的變數、給範圍鏈的外部環境參考,以及特殊關鍵字 this,在最後 JavaScript 其實還設定了一個特別的關鍵字 arguments

arguments

那 arguments 是什麼?arguments 包含了所有的值,所有我們傳入函數的參考的意思。

arguments

arguments 是參數的一種概念,只是我們傳入函數的變數的另一種稱呼罷了,所以又可以稱為 parameters,這樣講很模糊,所以從範例程式碼來瞭解什麼是 arguments ↓

1
2
3
4
5
6
function greet(firstName, lastName, languaue) {
console.log(firstName);
console.log(lastName);
console.log(languaue);
}
greet();

JavaScript 與其他語言最大不同之處就是可以不用帶入任何參數也能正常執行,儘管函數上面有需要帶入的參數,但卻也不會跳錯誤。

不用帶入任何參數也能正常執行

可以看到我們的函數參數被賦予預設值 undefined * 3,所以我們也可以知道一件事情。

函數的參數,就是變數的一種

那如果我們開始傳入參數,它會由最左邊至右邊依序加入 ↓

1
2
3
4
5
6
7
8
function greet(firstName, lastName, languaue) {
console.log(firstName);
console.log(lastName);
console.log(languaue);
}
greet();
console.log('-----')
greet('Mary');

Mary

那我們一樣繼續傳入參數 ↓

1
2
3
4
5
6
7
8
9
10
11
12
function greet(firstName, lastName, languaue) {
console.log(firstName);
console.log(lastName);
console.log(languaue);
}
greet();
console.log('-----')
greet('Mary');
console.log('-----')
greet('Mary','Tomy');
console.log('-----')
greet('Mary','Tomy','us');

最左邊至右邊依序

這樣代表著一件事情,我們可以忽略傳入參數,只傳入特定參數,但是在原生 JavaScript 函數參數是不能賦予預設值參數,所以如果需要使用預設參數,就必須使用以下這個方法 ↓

1
2
3
4
5
6
7
function greet(firstName, lastName, languaue) {
firstName = firstName || 'jack';
console.log(firstName);
console.log(lastName);
console.log(languaue);
}
greet();

預設參數

回頭來講一下剛剛前面講的 arguments,JavaScript 在執行環境建立時替我們準備好了一個 arguments,那 arguments 是什麼鬼?讓我們將它輸出至 console 看看 ↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function greet(firstName, lastName, languaue) {
firstName = firstName || 'jack';
console.log(firstName);
console.log(lastName);
console.log(languaue);
console.log(arguments);
}
greet();
console.log('-----')
greet('Mary');
console.log('-----')
greet('Mary','Tomy');
console.log('-----')
greet('Mary','Tomy','us');

arguments

我們可以發現一件事情,arguments 其實是一個陣列,而且包含了我們所有傳入的參數值,但是要注意 arguments 是一個類陣列,因為參數在 JavaScript 是一個特別的東西,正因為它是類陣列,所以它只能使用部分陣列的功能。

如果沒有傳入任何參數,我們可以嘗試使用 length 來檢查陣列長度 ↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function greet(firstName, lastName, languaue) {
firstName = firstName || 'jack';
console.log(firstName);
console.log(lastName);
console.log(languaue);
console.log(arguments.length);
}
greet();
console.log('-----')
greet('Mary');
console.log('-----')
greet('Mary','Tomy');
console.log('-----')
greet('Mary','Tomy','us');

arguments.length

當然也可以透過使用 arguments 取值 ↓

1
2
3
4
5
6
7
8
9
10
11
12
13
function greet(firstName, lastName, languaue) {
firstName = firstName || 'jack';
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
greet();
console.log('-----')
greet('Mary');
console.log('-----')
greet('Mary','Tomy');
console.log('-----')
greet('Mary','Tomy','us');

arguments 取值

但是你會發現一件事情,我們設置的 firstName = firstName || 'jack'; 就沒有效果煩而是 undefined,所以在使用 arguments 來直接取值要小心。

spread (其餘參數)

spread 是在 ES6 加入的新功能,讓我們看看範例。

1
2
3
4
5
6
7
8
9
10
11
12
13
function greet(firstName, lastName, languaue) {
firstName = firstName || 'jack';
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
greet();
console.log('-----')
greet('Mary');
console.log('-----')
greet('Mary','Tomy');
console.log('-----')
greet('Mary','Tomy','us','123','test');

我們可以看到最後一行後面多了兩個參數 greet('Mary','Tomy','us','123','test');,那 spread 該怎麼用?當我們不確定傳入的參數數量時,就可以使用 spread ↓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function greet(firstName, lastName, languaue,...other) {
firstName = firstName || 'jack';
console.log(firstName);
console.log(lastName);
console.log(languaue);
console.log(other);
}
greet();
console.log('-----')
greet('Mary');
console.log('-----')
greet('Mary','Tomy');
console.log('-----')
greet('Mary','Tomy','us','123','test');

只要寫入 ... + 參數名稱,這樣就可以了。

spread

取值的方式就不再多述就像陣列取值一樣。

圖源

JavaScript 全攻略:克服 JS 奇怪的部分

0%