Spread Syntax (展開語法)
概念
- 展開語法允許將一個可迭代的物件 (例如:陣列、字串、Set、Map 等) 「展開」成個別的元素。
- 使用三個點
...
作為語法標示。
應用場景
- 複製陣列/物件 (淺拷貝)
// 陣列
const arr1 = [1, 2, 3];
const arr2 = [...arr1]; // arr2: [1, 2, 3] (獨立的副本)
// 物件
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // obj2: { a: 1, b: 2, c: 3 } (合併並新增屬性)
注意: 這屬於淺拷貝,僅複製物件的第一層結構,而不會複製底下第二層之後的物件,第二層之後的物件使用內部物件的記憶體位址。如果物件或陣列內部有巢狀結構,修改複製後的內部結構會影響到原始物件或陣列。
// 陣列
const arr1 = [1, 2, [3, 4]];
const arr2 = [...arr1]; // 淺拷貝
arr2[0] = 10; // arr1[0] 不會受影響
arr2[2][0] = 30; // arr1[2][0] 會被影響 (因為複製的是記憶體位址)
console.log(arr1); // [1, 2, [30, 4]]
console.log(arr2); // [10, 2, [30, 4]]
// 物件
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { ...obj1 }; // 淺拷貝
obj2.a = 10; // obj1.a 不會受影響
obj2.b.c = 20; // obj1.b.c 會被影響 (因為複製的是記憶體位址)
console.log(obj1); // {a: 1, b: {c: 20}}
console.log(obj2); // {a: 10, b: {c: 20}}
- 合併陣列
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2]; // combined: [1, 2, 3, 4]
- 傳遞函數參數 (取代 apply 方法)
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
const result = sum(...numbers); // result: 6
- 將字串展開成字符陣列
const str = "hello";
const chars = [...str]; // chars: ['h', 'e', 'l', 'l', 'o']
- 解構賦值時提取部分元素
const arr = [1, 2, 3, 4, 5];
const [first, second, ...rest] = arr; // first: 1, second: 2, rest: [3, 4, 5]
- 將NodeList等類陣列轉換為真正的陣列
const nodeList = document.querySelectorAll('li');
const array = [...nodeList]
Rest Parameters (其餘參數)
概念
- 其餘參數允許將不特定數量的參數打包成一個陣列。
- 使用三個點
...
作為語法標示,只能在函數參數的最後一個位置使用。
應用場景
- 處理不定數量的函數參數
function myFunc(a, b, ...rest) {
console.log("a:", a); // 1
console.log("b:", b); // 2
console.log("rest:", rest); // [3, 4, 5]
}
myFunc(1, 2, 3, 4, 5);
- 取代
arguments
物件
arguments
物件是早期 JavaScript 中用來存取函數所有參數的類陣列物件,但其限制較多。
Rest Parameters 可以更清晰且彈性地處理不定數量的參數,並且是一個真正的陣列。
// 使用 arguments (早期做法)
function sumArgs() {
let sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(sumArgs(1, 2, 3, 4)); // 輸出 10
// 使用 Rest Parameters (現代做法),處理不定數量的參數
function sumAll(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sumAll(1, 2, 3, 4)); // 輸出 10
// 對比: Spread Syntax 傳入固定數量參數
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 輸出 6 ,使用 Spread Syntax 展開陣列
//console.log(sum(1,2,3,4)) // Error
重點整理
本篇文章探討了 JavaScript 中兩個重要的 ES6 特性:Spread Syntax (展開語法) 和 Rest Parameters (其餘參數)。
這兩者都使用 ...
符號,但它們的作用和應用場景截然不同。
- Spread Syntax 主要用於展開可迭代物件,例如將陣列或物件的元素複製到新的陣列或物件中,或是在函式呼叫時傳遞參數。它的作用就像一個「展開器」,能讓你更簡潔地處理資料。
- Rest Parameters 則用於收集不定數量的函數參數,將它們打包成一個陣列,方便在函數內部進行處理。它就像一個「收集器」,可以讓你的函數更靈活地接收參數。