欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ECMAScript 6即將帶給我們新的數(shù)組操作方法前瞻

 更新時(shí)間:2015年01月06日 10:00:33   投稿:hebedich  
這篇文章主要介紹了ECMAScript 6即將帶給我們新的數(shù)組操作方法前瞻,需要的朋友可以參考下

本文介紹ECMAScript 6即將帶給我們新的數(shù)組操作方法,以及在怎樣在現(xiàn)有瀏覽器應(yīng)用這些新的數(shù)組特性。

Note: 我將使用交替使用構(gòu)造器(constructor)和類(class)兩個(gè)術(shù)語。

類方法
數(shù)組(Array)自身所擁有的方法。

Array.from(arrayLike, mapFunc?, thisArg?)

Array.from()的基本功能是,轉(zhuǎn)換兩種類型的對象成數(shù)組。

類數(shù)組對象(Array-like objects)

該類對象有長度與索引的屬性。DOM操作符的結(jié)果即屬于該類,如document.getElementsByClassName()。

可迭代對象(Iterable objects)

這類對象在取值時(shí),每次只能取一個(gè)元素。數(shù)組是可迭代的,就如ECMAScript中新的數(shù)組結(jié)構(gòu),映射(Map)和集(Set)。

以下代碼是一個(gè)轉(zhuǎn)換類數(shù)組對象到數(shù)組的一個(gè)示例:

復(fù)制代碼 代碼如下:

let lis = document.querySelectorAll('ul.fancy li');
Array.from(lis).forEach(function (li) {
  console.log(node);
});

querySelectorAll()的結(jié)果不是一個(gè)數(shù)組,也不會有forEach()這個(gè)方法。這是我們需要在使用這個(gè)方法之前,將它轉(zhuǎn)換成數(shù)組的原因。

通過Array.from()使用Mapping
Array.from()同樣也是一個(gè)泛型使用map()的替代選擇。

復(fù)制代碼 代碼如下:

let spans = document.querySelectorAll('span.name');
// map(), generically:
let names1 = Array.prototype.map.call(spans, s => s.textContent);
// Array.from():
let names2 = Array.from(spans, s => s.textContent);

兩個(gè)方法中的第二個(gè)參數(shù),都是箭頭函數(shù)(arrow function)。
在這個(gè)示例中,document.querySelectorAll()的結(jié)果又是一個(gè)類數(shù)組對象,而非數(shù)組。這就是我們不能直接調(diào)用map()的原因。第一個(gè)示例中,為了使用forEach(),我們將類數(shù)組對象轉(zhuǎn)換成了數(shù)組。這里我們通過泛型方法和兩個(gè)參數(shù)版本的Array.from(),而省去了中間步驟。

Holes
Array.from()會忽略數(shù)組里缺失的元素 - 洞(holes),它會以未定義的元素(undefined elements)進(jìn)行對待。

復(fù)制代碼 代碼如下:

> Array.from([0,,2])
[ 0, undefined, 2 ]

這就意味著,你可以使用Array.from()來創(chuàng)建或者填充一個(gè)數(shù)組:

復(fù)制代碼 代碼如下:

> Array.from(new Array(5), () => 'a')
[ 'a', 'a', 'a', 'a', 'a' ]
> Array.from(new Array(5), (x,i) => i)
[ 0, 1, 2, 3, 4 ]

如果你想用一個(gè)固定的值去填充一個(gè)數(shù)組,那么Array.prototype.fill()(請看下文)將是一個(gè)更好的選擇。第一個(gè)即是以上示例的兩種方式。

在數(shù)組(Array)子類中的from()
另一個(gè)Array.from()的使用場景是,轉(zhuǎn)換類數(shù)組對象或可迭代對象到一個(gè)數(shù)組(Array)子類的一個(gè)實(shí)例。如你創(chuàng)建了一個(gè)Array的子類MyArray,想將此類對象轉(zhuǎn)化成MyArray的一個(gè)實(shí)例,你就可以簡單地使用MyArray.from()??梢赃@樣使用的原因是,在ECMAScript 6中構(gòu)造器(constructors)會繼承下去(父類構(gòu)造器是它子類構(gòu)造器的原型(prototype))。

復(fù)制代碼 代碼如下:

class MyArray extends Array {
  ...
}
let instanceOfMyArray = MyArray.from(anIterable);

你可以將該功能與映射(mapping)結(jié)合起來,在一個(gè)你控制結(jié)果構(gòu)造器的地方完成映射操作(map operation):

復(fù)制代碼 代碼如下:

// from() – determine the result's constructor via the receiver
// (in this case, MyArray)
let instanceOfMyArray = MyArray.from([1, 2, 3], x => x * x);
// map(): the result is always an instance of Array
let instanceOfArray   = [1, 2, 3].map(x => x * x);
Array.of(...items)

如果你想將一組值轉(zhuǎn)換成一個(gè)數(shù)組,你應(yīng)該使用數(shù)組源文本(array literal)。特別是只有一個(gè)值且還是數(shù)字的時(shí)候,數(shù)組的構(gòu)造器便罷工了。更多信息請參考。

復(fù)制代碼 代碼如下:

> new Array(3, 11, 8)
[ 3, 11, 8 ]
> new Array(3)
[ , ,  ,]
> new Array(3.1)
RangeError: Invalid array length

便如果要將一組值轉(zhuǎn)換成數(shù)字子構(gòu)造器(sub-constructor)的一個(gè)實(shí)例,我們應(yīng)該怎么做呢?這就是Array.of()存在的價(jià)值(記住,數(shù)組子構(gòu)造器會繼承所有的數(shù)組方法,當(dāng)然也包括of())。

復(fù)制代碼 代碼如下:

class MyArray extends Array {
  ...
}
console.log(MyArray.of(3, 11, 8) instanceof MyArray); // true
console.log(MyArray.of(3).length === 1); // true

把值包裹嵌套在數(shù)組里,Array.of()會相當(dāng)方便,而不會有Array()一樣怪異的處理方式。但也要注意Array.prototype.map(),此處有坑:

復(fù)制代碼 代碼如下:

> ['a', 'b'].map(Array.of)
[ [ 'a', 0, [ 'a', 'b' ] ],
[ 'b', 1, [ 'a', 'b' ] ] ]
> ['a', 'b'].map(x => Array.of(x)) // better
[ [ 'a' ], [ 'b' ] ]
> ['a', 'b'].map(x => [x]) // best (in this case)
[ [ 'a' ], [ 'b' ] ]

如你所看,map()會傳遞三個(gè)參數(shù)到它的回調(diào)里面。最后兩個(gè)又是經(jīng)常被忽略的(詳細(xì))。

原型方法(Prototype methods)
數(shù)組的實(shí)例會有很多新的方法可用。

數(shù)組里的迭代(Iterating over arrays)

以下的方法,會幫助完成在數(shù)組里的迭代:

復(fù)制代碼 代碼如下:

Array.prototype.entries()
Array.prototype.keys()
Array.prototype.values()

以上的每一個(gè)方法都會返回一串值,卻不會作為一個(gè)數(shù)組返回。它們會通過迭代器,一個(gè)接一個(gè)的顯示。讓我們看一個(gè)示例(我將使用Array.from()將迭代器的內(nèi)容放在數(shù)組中):

復(fù)制代碼 代碼如下:

> Array.from([ 'a', 'b' ].keys())
[ 0, 1 ]
> Array.from([ 'a', 'b' ].values())
[ 'a', 'b' ]
> Array.from([ 'a', 'b' ].entries())
[ [ 0, 'a' ],
[ 1, 'b' ] ]

你可以結(jié)合entries()和ECMAScript 6中的for-of循環(huán),方便地將迭代對象拆解成key-value對:

復(fù)制代碼 代碼如下:

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}

Note: 這段代碼已經(jīng)可以在最新的Firefox瀏覽器里運(yùn)行了。t Firefox.

查找數(shù)組元素

Array.prototype.find(predicate, thisArg?) 會返回滿足回調(diào)函數(shù)的第一個(gè)元素。如果沒有任何一個(gè)元素滿足條件,它會返回undefined。比如:

復(fù)制代碼 代碼如下:

> [6, -5, 8].find(x => x < 0)
-5
> [6, 5, 8].find(x => x < 0)
undefined
Array.prototype.findIndex(predicate, thisArg?)

會返回滿足回調(diào)函數(shù)的第一個(gè)元素的索引。如果找不任何滿足的元素,則返回-1。比如:

復(fù)制代碼 代碼如下:

> [6, -5, 8].findIndex(x => x < 0)
1
> [6, 5, 8].findIndex(x => x < 0)
-1

兩個(gè)find*方法都會忽略洞(holes),即不會關(guān)注undefined的元素?;卣{(diào)的完成函數(shù)簽名是:

predicate(element, index, array)
通過findIndex()找NaN

Array.prototype.indexOf()有一個(gè)大家所熟知的限制,那就是不能查找NaN。因?yàn)樗煤愕?===)查找匹配元素:

復(fù)制代碼 代碼如下:

> [NaN].indexOf(NaN)
-1

使用findIndex(),你就可以使用Object.is(),這就不會產(chǎn)生這樣的問題:

復(fù)制代碼 代碼如下:

> [NaN].findIndex(y => Object.is(NaN, y))
0

你同樣也可以采用更通用的方式,創(chuàng)建一個(gè)幫助函數(shù)elemIs():

復(fù)制代碼 代碼如下:

> function elemIs(x) { return Object.is.bind(Object, x) }
> [NaN].findIndex(elemIs(NaN))
0
Array.prototype.fill(value, start?, end?)

用所給的數(shù)值,填充一個(gè)數(shù)組:

復(fù)制代碼 代碼如下:

> ['a', 'b', 'c'].fill(7)
[ 7, 7, 7 ]

洞(Holes)也不會有任何的特殊對待:

復(fù)制代碼 代碼如下:

> new Array(3).fill(7)
[ 7, 7, 7 ]

你也可以限制你填充的起始與結(jié)束:

復(fù)制代碼 代碼如下:

> ['a', 'b', 'c'].fill(7, 1, 2)
[ 'a', 7, 'c' ]

什么時(shí)候可以使用新的數(shù)組方法?
有一些方法已經(jīng)可以在瀏覽器里使用了。

相關(guān)文章

最新評論