[Javascript] ES6 Spread Syntax 展開語法

Spread Syntax 表示。

Les Lee
一個小小工程師的隨手筆記
6 min readDec 9, 2018

--

在自然用語中,我們會使用 作為一種表示「剩下的、其他」的意思。

在 Javascript ES6 中,納入了這種 三個點(...)的用法。可以很輕鬆的表示 Array 中 「剩下的」Elements,或是 call function 時給予 「其他的」parameters。

Spread Syntax 允許在創建 Array 時,將一個 Array、或 string 在語法層面展開 (expand)其內容成為個別數值(Value);還可以在 創建 Object 時,將來源 Object 按照 key-value的方式展開;或是在 function call 時對傳入參數、接收參數進行展開」的速寫語法 — MDN doc

講起來很饒口,我們直接來看幾個例子會更快瞭解。

將 array array1 的內容展開給 array2

以往我們要將 array2 的內容擴展給 array1 要不就是用迴圈一個一個倒過去(例如下面例子)

var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8];
array2.forEach( num => array1.push(num) )
console.log( array1 ) // [ 1, 2, 3, 4, 5, 6, 7, 8 ]

不然就是用 Array.concat() (例如下面例子)

var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8];
array1 = array1.concat(array2)
console.log( array1 ) // [ 1, 2, 3, 4, 5, 6, 7, 8 ]

如今,有了使用 Spread Operator 我們就可以很優雅的表示這個過程。

string str1 的內容展開給 result_ary

由於 Javascript 可以將 string 視作 character array 般巡行 (類似 C 中的字元陣列),因此我們利用此特性將 string 展開成 array。

將 Object object1 的內容展開給 object2

除了 Array 的擴展之外我們也可以使用在 Object 上。以往我們在將 object1 的內容給 object2 時,如同 array 的做法,不是使用迴圈一個一個 assign (如下面例子)

var object1 = {"a": 1, "b": 2, "c": 3, "d": 4};
var object2 = {"e": 5, "f": 6, "g": 7, "h": 8};
for ( let key in object1 ) {
// 將 object1 的內容在 object2 中創建
object2[key] = object1[key];
}
console.log( object2 )
// {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8}

不然就是使用 Object.assign (如下面例子)

var object1 = {"a": 1, "b": 2, "c": 3, "d": 4};
var object2 = {"e": 5, "f": 6, "g": 7, "h": 8};
Object.assign(object2, object1);console.log( object2 )
// {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8}

Object 方面,我們也可以使用 Spread Syntax 優雅地完成以前需要大費周章才能達成的目標

var object1 = {"a": 1, "b": 2, "c": 3, "d": 4};
var object2 = {"e": 5, "f": 6, "g": 7, "h": 8};
// 將 object1, 跟 object2 展開成新的 object 給 object2
object2 = {...object1, ...object2};
console.log( object2 )
// {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8}

這邊要注意的是,若是 object2 中有 key 是與 object1 相同的話,輸出的內容可能會因為 object2 較晚展開,而覆蓋 object1 對於此 key 所設定的內容。

在 Function parameters 中使用 Spread Syntax

Javascript 是一個很靈活的程式語言,他可以允許動態數量的參數內容。

因此我們可以在定義參數時利用 Spread Syntax 來表示 「剩下要傳入的參數們」這種概念。

以下方這個 加法 function 為例,平常我們只想做兩個數值的相加,但是利用 Spread Syntax 我們可以做到兩個以上數值的相加。

在上面的 code 中, others 會將剩下傳入的參數「全部接收」,變成一個 array,因此當我們使用 add(1, 2, 3, 4) 時,其實 others 得到的會是 [1, 2, 3, 4]這樣的結構。

如此寫法的好處在於其 大大簡化了獲取多餘參數的寫法。

以往我們可能需要利用 arguments.length 判斷參數數量,並且手動切出額外的參數才能進行相應的動作,如今有了 Spread Syntax 後我們便不需要進行如此繁瑣的事項了。

以往我們可能需要這樣寫

如今上面的程式我們可以改成

利用 Spread Syntax 於傳參時展開傳入的參數

我們能在 Function 定義參數時使用 Spread Syntax,當然也能在 Function call 時使用。

假定有一個 function 如下表示,接收4個參數。

function func1(a, b, c, d) { 
console.log("a:", a, ", b:", b, ", c:", c, ", d:", d)
}

我們以往需要 value by value 地傳入各自的數值:

func1(1, 2, 3, 4) // a:1, b:2, c:3, d:4

如今可以利用 Spread Syntax 將 array 傳入時自動展開,會得到如上相同的效果。

func1(...[1, 2, 3, 4]) // a:1, b:2, c:3, d:4

要注意的是,若是 array 中的 elements 數量多於 function 接收的參數數量,a, b, c, d 依然只會吃到 1, 2, 3, 4。array 剩下的內容要從 arguments 去獲取喔!

例如下面的例子:

function func1(a, b, c, d) { 
console.log("a:", a, "b:", b, "c:", c, "d:", d);
console.log("params", Array.prototype.slice.call( arguments ))
}
func1(...[1, 2, 3, 4, 5, 6, 7, 8])
// a: 1 b: 2 c: 3 d: 4
// params [1, 2, 3, 4, 5, 6, 7, 8]

結論

其實 Spread Syntax 就是一個語法糖,不了解基本上也不會怎麼樣。但是多學到一種寫法,可以讓我們的程式碼更加優美,何樂而不為呢?

如果這篇對你有幫助,請不要吝情於給我一點鼓勵。

--

--

Les Lee
一個小小工程師的隨手筆記

對新事物總是興緻勃勃、嘗試新技術、解決新挑戰; 也時常陷入許多無謂的思索,卡在其中得不出答案。