ECMAScript 6 學習筆記(七):陣列的擴充套件
擴充套件運算子
相當於 rest 引數的逆運算,同樣也是三個點(...
),用來將一個數組轉為逗號分隔的引數序列。該運算子主要用於函式呼叫。需要注意的是,擴充套件運算子放在括號中會被當成函式呼叫,此時若不是函式呼叫就會報錯。擴充套件運算子內部呼叫的是資料結構的 Iterator 介面,因此只要具有 Iterator 介面的物件,都可以使用擴充套件運算子。
function foo(...argus) { console.log(...argus); } foo(1, 2, 3); // 1 2 3 //第一個...把引數“1, 2, 3”轉為陣列[1, 2, 3] //第二個...把陣列[1, 2, 3]轉為引數序列“1, 2, 3” console.log((...[1, 2])) // Uncaught SyntaxError: Unexpected number
由於擴充套件運算子可以展開陣列,所以不再需要apply()
方法,將陣列轉為函式的引數了。
var arr = [2, 5, 11, 23]; // ES5 Math.max.apply(null, arr); // ES6 Math.max(...arr);
擴充套件運算子的應用
- 複製陣列
// ES5 寫法 var a1 = [1, 2, 3]; var a2 = a1.concat(); // ES6 寫法 var a1 = [1, 2, 3]; // 寫法一 var a2 = [...a1]; // 寫法二 var [...a2] = a1;
- 合併陣列
// ES5 寫法 var a1 = [1, 2]; var a2 = [3, 4]; var a3 = a1.concat(a2); // 淺拷貝 // ES6 寫法 var a1 = [1, 2]; var a2 = [3, 4]; var a3 = [...a1, ...a2]; // 淺拷貝
- 解構賦值
var arr = [1, 2, 3, 4]; [a, ...b] = arr; // a: 1, b: [2, 3, 4]
- 字串
[..."hello"] // ["h", "e", "l", "l", "o"]
新增陣列方法
Array.from()
這個方法用於將類陣列物件和可遍歷物件轉為真正的陣列。
// ES5 寫法 function foo() { return [].slice.call(arguments); } console.log(foo(1, 2, 3)) // [1, 2, 3] // Array.from() function bar() { return Array.from(arguments); } console.log(bar(1, 2, 3)) // [1, 2, 3]
同時可以利用第二個引數實現類似map()
的方法
Array.from(arrLike, x => x * x); //等同於 Array.from(arrLike).map(x => x * x);
Array.of()
這個方法用於將一組值轉為陣列,用來代替Array()
或者new Array()
。
新增陣列例項方法
copyWithin()
在陣列內部,將指定位置的資料複製到其他位置(覆蓋),然後返回當前陣列:
Array.prototype.copyWithin(target, start = 0, end = this.length) // *target:從該位置開始替換資料,負數時表示倒數。 // start:從該位置開始讀取資料,預設為0,負數時表示倒數。 // end:到該位置前停止讀取資料,預設為陣列長度,負數時表示倒數。 [1, 2, 3, 4, 5].copyWithin(0, 3); // [4, 5, 3, 4, 5]
find() 和 findIndex()
find()
方法找出第一個滿足回撥函式的成員並返回,若沒有符合條件的則返回undefined
。該回調函式接受三個引數,依次為當前的值、當前的位置和原陣列。findIndex()
方法與find()
方法類似,返回第一個滿足回撥函式的成員的位置,若沒有符合的返回-1
。這兩個方法都支援第二個引數,用來繫結回撥函式的this
物件。
[1, 5, 10, 15].find(function(value, index, arr) { return value > 9; }) // 10 [1, 5, 10, 15].findIndex(function(value, index, arr) { return value > 9; }) // 2
fill()
使用給定值填充陣列,常用於初始化陣列。fill()
方法接受3個引數,第一個是用來填充陣列的值,第二第三個引數對應指定填充的起始位置和結束位置。
[1, 2, 3, 4, 5, 6].fill(0, 2, 4) // [1, 2, 0, 0, 5, 6]
entries(),keys() 和 values()
這三個方法都是用來遍歷陣列並返回一個遍歷器物件,可以用for...of
迴圈遍歷。它們的區別在於keys()
遍歷鍵名、values()
遍歷鍵值、entries()
遍歷鍵值對。
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"
includes()
判斷陣列是否包含給定的值,返回一個布林值,類似於字串的includes
方法。該方法第一個引數為需要尋找的值,第二個引數為開始尋找的起始位置,如果該值為負數則表示倒數的位置,如果大於陣列長度則會從0重新開始計數。
[1, 2, 3].includes(1)// true [1, 2, 3].includes(4)// false [1, 2, NaN].includes(NaN) // true [1, 2, 3].includes(3, 3);// false [1, 2, 3].includes(3, -1); // true
flat() 和 flatMap()
flat()
用於將巢狀的陣列降維並返回一個新的陣列,可以通過引數設定需要降低幾層巢狀陣列,設為Infinity
則不管有多少層巢狀,都轉為一維陣列。如果原陣列有空位,flat()
方法會跳過空位。
[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]] [1, 2, [3, [4, 5]]].flat(2) // [1, 2, 3, 4, 5] [1, [2, [3]]].flat(Infinity) // [1, 2, 3] [1, 2, , 4, 5].flat() // [1, 2, 4, 5]
flatMap()
方法相當於對陣列執行map()
方法後再對返回的陣列執行flat()
方法並返回一個全新的陣列,但是隻能展開一層陣列。該方法的具體引數見示例下方程式碼,與map()
方法類似。
// 相當於 [[[2]], [[4]], [[6]], [[8]]].flat() [1, 2, 3, 4].flatMap(x => [[x * 2]]) // [[2], [4], [6], [8]] arr.flatMap(function callback(currentValue[, index[, array]]) { // ... }[, thisArg])
陣列的空位
陣列的空位指,陣列的某一個位置沒有任何值。比如,Array建構函式返回的陣列都是空位。空位不是undefined
,空位表示沒有任何值。
Array(3) // [, , ,]
ES5 中各方法對空位的處理非常不一致,大多數情況下會忽略,而 ES6 則明確地把空位轉成undefined
。
// forEach方法 [,'a'].forEach((x,i) => console.log(i)); // 1 // filter方法 ['a',,'b'].filter(x => true) // ['a','b'] // every方法 [,'a'].every(x => x==='a') // true // reduce方法 [1,,2].reduce((x,y) => x+y) // 3 // some方法 [,'a'].some(x => x !== 'a') // false // map方法 [,'a'].map(x => 1) // [,1] // join方法 [,'a',undefined,null].join('#') // "#a##" // toString方法 [,'a',undefined,null].toString() // ",a,,"