本文介紹ECMAScript 6即將帶給我們新的數組操作方法,以及在怎樣在現有瀏覽器應用這些新的數組特性。
Note: 我將使用交替使用構造器(constructor)和類(class)兩個術語。
類方法
數組(Array)自身所擁有的方法。
Array.from(arrayLike, mapFunc?, thisArg?)
Array.from()的基本功能是,轉換兩種類型的對象成數組。
類數組對象(Array-like objects)
該類對象有長度與索引的屬性。DOM操作符的結果即屬于該類,如document.getElementsByClassName()。
可迭代對象(Iterable objects)
這類對象在取值時,每次只能取一個元素。數組是可迭代的,就如ECMAScript中新的數組結構,映射(Map)和集(Set)。
以下代碼是一個轉換類數組對象到數組的一個示例:
querySelectorAll()的結果不是一個數組,也不會有forEach()這個方法。這是我們需要在使用這個方法之前,將它轉換成數組的原因。
通過Array.from()使用Mapping
Array.from()同樣也是一個泛型使用map()的替代選擇。
兩個方法中的第二個參數,都是箭頭函數(arrow function)。
在這個示例中,document.querySelectorAll()的結果又是一個類數組對象,而非數組。這就是我們不能直接調用map()的原因。第一個示例中,為了使用forEach(),我們將類數組對象轉換成了數組。這里我們通過泛型方法和兩個參數版本的Array.from(),而省去了中間步驟。
Holes
Array.from()會忽略數組里缺失的元素 - 洞(holes),它會以未定義的元素(undefined elements)進行對待。
這就意味著,你可以使用Array.from()來創建或者填充一個數組:
如果你想用一個固定的值去填充一個數組,那么Array.prototype.fill()(請看下文)將是一個更好的選擇。第一個即是以上示例的兩種方式。
在數組(Array)子類中的from()
另一個Array.from()的使用場景是,轉換類數組對象或可迭代對象到一個數組(Array)子類的一個實例。如你創建了一個Array的子類MyArray,想將此類對象轉化成MyArray的一個實例,你就可以簡單地使用MyArray.from()。可以這樣使用的原因是,在ECMAScript 6中構造器(constructors)會繼承下去(父類構造器是它子類構造器的原型(prototype))。
你可以將該功能與映射(mapping)結合起來,在一個你控制結果構造器的地方完成映射操作(map operation):
如果你想將一組值轉換成一個數組,你應該使用數組源文本(array literal)。特別是只有一個值且還是數字的時候,數組的構造器便罷工了。更多信息請參考。
便如果要將一組值轉換成數字子構造器(sub-constructor)的一個實例,我們應該怎么做呢?這就是Array.of()存在的價值(記住,數組子構造器會繼承所有的數組方法,當然也包括of())。
把值包裹嵌套在數組里,Array.of()會相當方便,而不會有Array()一樣怪異的處理方式。但也要注意Array.prototype.map(),此處有坑:
如你所看,map()會傳遞三個參數到它的回調里面。最后兩個又是經常被忽略的(詳細)。
原型方法(Prototype methods)
數組的實例會有很多新的方法可用。
數組里的迭代(Iterating over arrays)
以下的方法,會幫助完成在數組里的迭代:
以上的每一個方法都會返回一串值,卻不會作為一個數組返回。它們會通過迭代器,一個接一個的顯示。讓我們看一個示例(我將使用Array.from()將迭代器的內容放在數組中):
你可以結合entries()和ECMAScript 6中的for-of循環,方便地將迭代對象拆解成key-value對:
Note: 這段代碼已經可以在最新的Firefox瀏覽器里運行了。t Firefox.
查找數組元素
Array.prototype.find(predicate, thisArg?) 會返回滿足回調函數的第一個元素。如果沒有任何一個元素滿足條件,它會返回undefined。比如:
會返回滿足回調函數的第一個元素的索引。如果找不任何滿足的元素,則返回-1。比如:
兩個find*方法都會忽略洞(holes),即不會關注undefined的元素?;卣{的完成函數簽名是:
predicate(element, index, array)
通過findIndex()找NaN
Array.prototype.indexOf()有一個大家所熟知的限制,那就是不能查找NaN。因為它用恒等(===)查找匹配元素:
使用findIndex(),你就可以使用Object.is(),這就不會產生這樣的問題:
你同樣也可以采用更通用的方式,創建一個幫助函數elemIs():
用所給的數值,填充一個數組:
洞(Holes)也不會有任何的特殊對待:
你也可以限制你填充的起始與結束:
什么時候可以使用新的數組方法?
有一些方法已經可以在瀏覽器里使用了。
新聞熱點
疑難解答
圖片精選