JavaScript數(shù)組一篇中介紹了ES6之前的數(shù)組方法。本篇介紹一下ES6里新增的數(shù)組方法。
- find,findIndex,inclueds
- fill,copyWithin
- keys,values,entries
- 靜態(tài)方法(from,of)
find,findIndex,inclueds
find用于找元素,返回第一個(gè)滿足條件的元素,找不到就返回undefined。函數(shù)聲明:[].find( function(value, index, array) { … }, [thisArg] );。參照MDN
第一個(gè)參數(shù)是回調(diào)函數(shù),它支持3個(gè)參數(shù),第1個(gè)是遍歷的數(shù)組內(nèi)容,第2個(gè)是對(duì)應(yīng)索引,第3個(gè)是數(shù)組自身。第二個(gè)參數(shù)thisArg可選,可用于以改變回調(diào)函數(shù)里面的this指針
var count = [1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
});
console.log(count); //10
findIndex用于找元素,返回第一個(gè)滿足條件的元素的位置,找不到就返回-1。函數(shù)聲明:[].findIndex( function(value, index, array) { … }, [thisArg] );,和上面find一樣,不贅述。參照MDN
var idx = [1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
});
console.log(idx); //2
這兩個(gè)方法都可以發(fā)現(xiàn)NaN,彌補(bǔ)了之前indexOf方法的不足。indexOf方法無(wú)法識(shí)別數(shù)組的NaN元素,但findIndex方法可以借助Object.is方法做到:
var idx1 = [NaN].indexOf(NaN);
console.log(idx1); //-1
var idx2 = [NaN].findIndex(y => Object.is(NaN, y));
console.log(idx2); //0
includes用于找元素,找到返回true,找不到返回false。函數(shù)聲明:[].includes(el, [start]);。參照MDN
第一個(gè)參數(shù)是查找的元素。第二個(gè)參數(shù)可選,表示開始查找的位置,不指定的話默認(rèn)為0,指定為負(fù)數(shù),表示倒著數(shù)。
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
以前要看數(shù)組中是否包含某元素用indexOf:if (arr.indexOf(el) !== -1) { … }。除了感覺(jué)有點(diǎn)不自然外,也無(wú)法判斷是否包含NaN?,F(xiàn)在用includes就沒(méi)這些問(wèn)題了。
fill,copyWithin
fill用于填充當(dāng)前數(shù)組,返回填充后的數(shù)組。函數(shù)聲明:[].fill(value, [start, [end]]);。參照MDN
第一個(gè)參數(shù)是填充的元素,后兩個(gè)參數(shù)可選,start是起始填充位置,不指定的話默認(rèn)為0。end是填充到哪個(gè)位置之前結(jié)束,不指定的話默認(rèn)到數(shù)組尾。位置可以指定負(fù)數(shù),表示倒著數(shù)。
var arr = [1, 2, 3];
console.log(arr.fill(4)); // [4, 4, 4]
console.log(arr.fill(4, 1)); // [1, 4, 4]
console.log(arr.fill(4, 1, 2)); // [1, 4, 3]
console.log(arr.fill(4, -3, -2)); // [4, 2, 3]
用上面第一行例子,即單個(gè)參數(shù),來(lái)初始化數(shù)組非常方便,數(shù)組中原有元素將全部被抹去。
copyWithin和fill很像,它用于將數(shù)組指定位置的元素復(fù)制到其他位置(會(huì)覆蓋原來(lái)該位置的元素),最后返回修改后的數(shù)組。函數(shù)聲明:[].copyWithin(target, [start, [end]]);。參照MDN
第一個(gè)參數(shù)和fill有區(qū)別,是從該位置開始替換元素。后兩個(gè)參數(shù)參照f(shuō)ill,不贅述
var arr = ['a', 'b', 'c', 'd', 'e', 'f'];
console.log(arr.copyWithin(0, 3)); // ['d', 'e', 'f', 'd', 'e', 'f']
表示將從index為3開始直到數(shù)組結(jié)束的成員(即def)讀取出來(lái),替換從0號(hào)位開始的元素(即覆蓋了abc)。
再看一個(gè)負(fù)數(shù)的例子:
var arr1 = [1, 2, 3, 4, 5];
console.log(arr1.copyWithin(-2, -3, -1)); // [1, 2, 3, 3, 4]
從倒數(shù)3位開始直到倒數(shù)1位(即34)讀取出來(lái),替換倒數(shù)2位(即覆蓋了45)
keys,values,entries
這3個(gè)方法都用于遍歷數(shù)組。都返回一個(gè)遍歷器對(duì)象,可以用for…of循環(huán)進(jìn)行遍歷。區(qū)別是keys是對(duì)key的遍歷,values是value的遍歷,entries是對(duì)key-value的遍歷。
函數(shù)聲明都非常簡(jiǎn)單,一個(gè)參數(shù)都沒(méi)有,分別是:[].keys();,[].values();,[].entries();。參照MDN
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
因?yàn)榉祷氐氖潜闅v器對(duì)象,因此除了for…of循環(huán)外,也可以手動(dòng)調(diào)用遍歷器對(duì)象的next方法來(lái)遍歷:
var arr = ['a', 'b', 'c'];
var eArr = arr.entries();
console.log(eArr.next().value); // [0, 'a']
console.log(eArr.next().value); // [1, 'b']
console.log(eArr.next().value); // [2, 'c']
靜態(tài)方法(from,of)
JavaScript數(shù)組一篇中介紹了ES6之前的數(shù)組方法,包括本篇上面所有Array的方法的函數(shù)聲明都用了“[].方法名”的形式,等價(jià)于“Array.prototype.方法”,表示它們都是Array的實(shí)例方法。
但form和of的函數(shù)聲明用了“Array.方法名”的形式,表示它們是Array的靜態(tài)方法。(關(guān)于JS靜態(tài)可以參照這里)
from用于將類數(shù)組對(duì)象轉(zhuǎn)為真正的數(shù)組。函數(shù)聲明:Array.from(arrayLike, [mapFn, [thisArg]]);。參照MDN
第一個(gè)參數(shù)自然就是類數(shù)組對(duì)象。第二個(gè)參數(shù)作用類似于map,還可以為map指定this。有關(guān)類數(shù)組對(duì)象和map方法請(qǐng)參照JavaScript數(shù)組,不贅述。
現(xiàn)在用ES6的from方法來(lái)重寫JavaScript數(shù)組一篇中的類數(shù)組對(duì)象中的例子:
處理arguments對(duì)象:
//ES5處理arguments對(duì)象:
var args = [].slice.call(arguments);
//ES6用from
var args = Array.from(arguments);
處理HTMLCollection對(duì)象:
//ES5用forEach遍歷頁(yè)面所有div,輸入className
var divs = document.getElementsByTagName("div");
Array.prototype.forEach.call(divs, function(div) {
console.log("該div類名是:" + (div.className || "空"));
});
// ES6用from
Array.from(divs).forEach(function (div) {
console.log("該div類名是:" + (div.className || "空"));
});
處理字面量對(duì)象:
//ES5
var arrayLike = { 0: "a", 1: "b", 2: "c", length: 3 };
var result = Array.prototype.map.call(arrayLike, function(s) {
return s.toUpperCase();
});
console.log(result); //["A", "B", "C"]
//ES6
var result = Array.from(arrayLike, s => s.toUpperCase());
console.log(result); //["A", "B", "C"]
上面from用了第二個(gè)參數(shù),該語(yǔ)句等價(jià)于Array.from(arrayLike).map(s => s.toUpperCase());
處理字符串:
//ES5
var result = Array.prototype.map.call("abc", function(s) {
return s.toUpperCase();
});
console.log(result); //["A", "B", "C"]
//ES6
var result = Array.from("abc", s => s.toUpperCase());
console.log(result); //["A", "B", "C"]
of作用和from類似,用于將一組值,轉(zhuǎn)換為數(shù)組。函數(shù)聲明:Array.of(el0, [el1, … , elN]);。參照MDN
和from一樣, 同樣是Array的靜態(tài)方法,你無(wú)法用數(shù)組對(duì)象調(diào)用of方法。
console.log(Array.of(1,2,3)); // [1, 2, 3]
你可能會(huì)很疑惑,直接var arr = new Array(1,2,3);不就行了,要of方法有什么用?如果只有1個(gè)參數(shù)就有區(qū)別了:
//只有1個(gè)參數(shù)的普通構(gòu)造函數(shù)
var arr1 = Array(3);
console.log(arr1); // [, , ,]
//ES6用of就和上面有區(qū)別了
var arr2 = Array.of(3);
console.log(arr2); // [3]
可以看出用of的話,可以完全替代構(gòu)造函數(shù),避免了單個(gè)參數(shù)導(dǎo)致的非常微妙的區(qū)別。它總是能返回一個(gè)數(shù)組,如果沒(méi)有參數(shù),就返回空數(shù)組[]