天天看點

ES6-數組的拓展1.擴充運算符2. Array.from()3 Array.of()4 數組執行個體方法

1.擴充運算符

擴充運算符(spread)是三個點**(…)**。它好比 rest 參數的逆運算,将一個數組轉為用逗号分隔的參數序列

console.log(...[1,2,3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
           

擴充運算符與正常的函數參數可以結合使用,非常靈活。

如果擴充運算符後面是一個空數組,則不産生任何效果。

注意,隻有函數調用時,擴充運算符才可以放在圓括号中,否則會報錯。

用Math.max方法,簡化求出一個數組最大元素的寫法。

通過push函數,将一個數組添加到另一個數組的尾部。

// ES5 的寫法
Math.max.apply(null, [14, 3, 77])

// ES6 的寫法
Math.max(...[14, 3, 77])

// 等同于
Math.max(14, 3, 77);

// ES5的 寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2);

// ES6 的寫法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);
           

1.1複制數組

const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]
           

a2 不是a1的克隆,是指向同一個資料的指針

複制:

//ES5
const a1 = [1, 2];
const a2 = a1.concat();

a2[0] = 2;
a1 // [1, 2]
//ES6
const a1 = [1,2];
//寫法1
const a2 = [...a1];
//寫法2
const [...a2]=a1;
           

複制方法 copyWithin()

1.2合并數組

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5 的合并數組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

// ES6 的合并數組
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
           

不過,這兩種方法都是淺拷貝,使用的時候需要注意

let ints = [0,1,2,3,4,5,6,7,8,9];
reset();
ints.copyWithin(5);
console.log(ints);//[0,1,2,3,4,0,1,2,3,4]
           

1.3與解構指派結合

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]

const [first, ...rest] = [];
first // undefined
rest  // []

const [first, ...rest] = ["foo"];
first  // "foo"
rest   // []
           

如果将擴充運算符用于數組指派,隻能放在參數的最後一位,否則會報錯。

擴充運算符還可以将字元串轉為真正的數組

[...'hello']
// [ "h", "e", "l", "l", "o" ]
           

2. Array.from()

Array.from方法用于将

  • 類似數組的對象
  • 可周遊的對象

    轉化為數組

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

// ES5的寫法
var arr1 = [].slice.call(arrayLike);
// ES6
let arr2 = Array.from(arrayLike);
           

擴充運算符背後調用的是周遊器接口(Symbol.iterator),如果一個對象沒有部署這個接口,就無法轉換。

Array.from方法還支援類似數組的對象。所謂類似數組的對象,本質特征隻有一點,即必須有length屬性。是以,任何有length屬性的對象,都可以通過Array.from方法轉為數組,而此時擴充運算符就無法轉換。

對于還沒有部署該方法的浏覽器,可以用Array.prototype.slice方法替代。

const toArray = (() =>
  Array.from ? Array.from : obj => [].slice.call(obj)
)();
           

Array.from還可以接受第二個參數,作用類似于數組的map方法,用來對每個元素進行處理,将處理後的值放入傳回的數組

Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);

Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]
           
  • 常用于初始化數組

    例:

const len = 3;
const init = 0;
const res1 = Array.from({ len },() => init);
res;//[0,0,0]
//二維數組
const res2 = Array.from({length: n}).map(() => new Array(n));
           

3 Array.of()

Array.of()方法用于将一組值,轉換為數組。

4 數組執行個體方法

4.1find() 和 findIndex()

數組執行個體的find方法,用于找出第一個符合條件的數組成員。它的參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個傳回值為true的成員,然後傳回該成員(與some()方法不一樣的地方)。如果沒有符合條件的成員,則傳回undefined

[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10
           

數組執行個體的findIndex方法的用法與find方法非常類似,傳回第一個符合條件的數組成員的位置,如果所有成員都不符合條件,則傳回-1

4.2 fill()

fill方法使用給定值,填充一個數組

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

new Array(3).fill(7)
// [7, 7, 7]
           
const zeroes = [0,0,0,0,0];
zeroes.fill(5);//[5,5,5,5,5]
//(-4 + zeroes.length = 1)
//(-1 + zeroes.length = 4)
zerose.fill(8,-4,-1);//[5,8,8,8,5]
           

fill()靜默忽略超出數組邊界、零長度及方向相反的索引範圍

fill方法還可以接受第二個和第三個參數,用于指定填充的起始位置和結束位置

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
           
  • 犯的錯誤:
const dp = []
dp[0][0]//這種寫法錯誤,因為js對于多元數組隻能層層定義
//以下寫法正确
const dp=[]
dp[0] = []
dp[0][0] = 0
const dp = new Array(5).fill([])
           

4.3entries(),keys() 和 values()

ES6 提供三個新的方法——entries(),keys()和values()——用于周遊數組。它們都傳回一個周遊器對象(詳見《Iterator》一章),可以用for…of循環進行周遊,唯一的差別是keys()是對鍵名的周遊、values()是對鍵值的周遊,entries()是對鍵值對的周遊

for(let index of ['a','b'].key()){
	...
}
for(let elem of ['a','b'].values()){
	...
}
for(let [index,elem] of ['a','b'].entries())

let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value);
console.log(entries.next().value);
console.log(entries.next().value);

           

4.4 includes()

Array.prototype.includes方法傳回一個布爾值,表示某個數組是否包含給定的值,與字元串的includes方法類似。ES2016 引入了該方法。

該方法的第二個參數表示搜尋的起始位置,預設為0。如果第二個參數為負數,則表示倒數的位置,如果這時它大于數組長度(比如第二個參數為-4,但數組長度為3),則會重置為從0開始。

4.5flat(),flatMap()

數組的成員有時還是數組,Array.prototype.flat()用于将嵌套的數組“拉平”,變成一維的數組。該方法傳回一個新數組,對原資料沒有影響。

[1, 2, [3, 4]].flat()
// [1, 2, 3, 4]
           

flat()預設隻會“拉平”一層,如果想要“拉平”多層的嵌套數組,可以将flat()方法的參數寫成一個整數,表示想要拉平的層數,預設為1。

flat(Infinity),不管幾層直接拉平

[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()方法對原數組的每個成員執行一個函數(相當于執行Array.prototype.map()),然後對傳回值組成的數組執行flat()方法。該方法傳回一個新數組,不改變原數組。

// 相當于 [[[2]], [[4]], [[6]], [[8]]].flat()
[1, 2, 3, 4].flatMap(x => [[x * 2]])
// [[2], [4], [6], [8]]
           
  • forEach(), filter(), reduce(), every() 和some()都會跳過空位。
  • map()會跳過空位,但會保留這個值
  • join()和toString()會将空位視為undefined,而undefined和null會被處理成空字元串。
// 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,,"

           

繼續閱讀