點燈坊

失くすものさえない今が強くなるチャンスよ

使用 fill() 一次改變 Array 內多個 Element

Sam Xiao's Avatar 2020-03-31

Array.prototype.fill() 為 ECMAScript 2015 才新增的 Method,可一次改變 Array 內多個 Element,也因此特殊功能,因而推導出一些獨特應用。

Version

macOS Catalina 10.15.4
VS Code 1.43.2
Quokka 1.0.284
ECMAScript 2015

Change Multiple Element

let data = [1, 2, 3]

data.fill(0, 1, 3) // ?

fill() 最原始應用是提供起始 index 與結束 index,可一次提供值修改多個 element。

fill()
arr.fill(value[, start[, end]])
一次改變 array 內多個 element

value:要改變的值

start:起始 index (可省略)

end:結束 index (可省略)

fill000

Change Multiple Element to End

let data = [1, 2, 3]

data.fill(0, 1) // ?

若省略 end argument 則表示修改到最後一個 element。

fill001

Change All Element

let data = [1, 2, 3]

data.fill(0) // ?

若連 startend 兩個 argument 都省略,則表示全部 element 都修改,這也是 fill() 最常見應用。

fill002

Create Array with Initial Value

let create = n => init => Array.from({ length: n }, () => init)

create(3)(0) // ?

若要建立 array 時一併提供預設值填滿,可使用 ES6 的 Array.from(),不過 length 必須以 object 提供,第二個 argument 必須是 function。

fill003

let create = n => init => Array(n).fill(init)

create(3)(0) // ?

由於 fill() 有一次改變所有 element 特性,使用 Array(n) 建立 array 後,可順勢使用 fill() 提供預設值,這也是 fill() 常見應用。

fill004

Side Effect

let data = [1, 2, 3]

let f = a => a.fill(0)

f(data) // ?

data // ?

fill() 看似好用,但卻有個致命傷,它會修改原本 array,也就是若 array 以 argument 傳進 function,由於 ECMAScript 對於 array 是 copy address,仍指向原本 array,因此 function 外的 array 也會被 fill() 修改。

fill005

Conclusion

  • 若想在建立 array 時一併提供預設值,則 fill()Array.from() 精簡直覺
  • fill() 為 ES6 所提供的新 method,竟然還會改變原本 array,是比較可惜之處,實務上需小心其 side effect

Reference

MDN, Array.prototype.fill()
MDN, Array.from()