ES6 陣列相關

Zingiber發表於2019-09-05

1.1擴充套件運算子(...)

1.1.1 用於函式呼叫

將一個陣列變為引數序列;可與正常的函式引數結合使用;擴充套件運算子後面也可以放表示式;如果擴充套件運算子後面是空陣列,不產生任何效果。只有函式呼叫時,擴充套件運算子才可以放到圓括號裡。

const array1 = [];
const array2 = [];
const arr = [1,2,3];
function push(array,...items){
  array.push(...items);
  console.log(...(items+'1')); // 1 , 2 , 3 1
}
push(array1,...arr);
push(array2,...[]);

array1 // [1,2,3]
array2 //[]
複製程式碼

1.1.2 替代Apply方法

apply方法的第二個引數把陣列轉換為函式的引數,有了擴充套件運算子,可以替代apply的這個作用

function f(x, y, z) {
  // ...
}

// ES5 的寫法
var args = [0, 1, 2];
f.apply(null, args);

// ES6的寫法
let args = [0, 1, 2];
f(...args);
複製程式碼

1.1.3 複製陣列

陣列是複合資料型別,直接複製只是複製了陣列的地址,沒有重新建立一個陣列。擴充套件運算子可以提供複製陣列的簡便方法。如果陣列成員是物件,只能複製物件的引用,如果修改了新陣列成員,會同步反映到原陣列(淺拷貝)

const a1 = [1, 2];
const a2 = a1;
// 只複製了a1的地址
a2[0] = 2;
a1 // [2, 2]

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

// 擴充套件運算子方法
const a2 = [...a1]; // 寫法一
const [...a2] = a1; // 寫法二
複製程式碼

1.1.4 合併陣列

提供了陣列合並的新寫法

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' ]
複製程式碼

1.1.5 結合解構賦值

擴充套件運算子可以與解構賦值結合生成陣列,只能把擴充套件運算子,會報錯

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

const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 報錯
複製程式碼

1.1.6 將字串轉為陣列

[...'hello']
// [ "h", "e", "l", "l", "o" ]
複製程式碼

1.1.7 將==定義了Iterator==介面的物件轉換為陣列

let nodeList = document.querySelectorAll('div');
let array = [...nodeList];

let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};
// 沒有部署Iterator介面的類似陣列的物件
// TypeError: Cannot spread non-iterable object.
let arr = [...arrayLike];
複製程式碼

1.1.8 帶有Iterator介面的物件可使用擴充套件運算子

擴充套件運算子背後呼叫的是遍歷器介面

// map結構
let map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]

// generator
const go = function*(){
  yield 1;
  yield 2;
  yield 3;
};
[...go()] // [1, 2, 3]
複製程式碼

1.2Array.from()

用於將類似陣列的物件和可遍歷的物件轉為真正的陣列。==物件裡必須有length屬性==,任何有length屬性對物件都可以通過Array.from()轉為陣列。擴充套件運算子也可以將某些資料結構轉為陣列。

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

// ES5
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

Array.from({ length: 3 });
// [ undefined, undefined, undefined ]
複製程式碼

Array.from()還可以接受第二個引數,作用類似陣列的map方法,用來對每個元素進行處理,處理後放入陣列。

Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]
複製程式碼

1.3Array.of()

將一組值轉為陣列,這個函式主要為了彌補建構函式Array()因為引數個數不同,導致Array()行為有差異的不足。

Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(3) // [3]
Array.of(1, 2) // [1, 2]
複製程式碼

1.4陣列例項的copyWithin()

把當前陣列內部指定位置的成員複製到其他位置(會覆蓋原有成員),然後返回當前陣列。可以修改當前陣列。

引數:

  1. target(必須):從該位置開始替換資料。如果為負值,表示倒數。
  2. start(可選):從該位置開始讀取資料,預設為 0。如果為負值,表示從末尾開始計算。
  3. end(可選):到該位置前停止讀取資料,預設等於陣列長度。如果為負值,表示從末尾開始計算。
// 將3號位複製到0號位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]

// -2相當於3號位,-1相當於4號位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]

// 將3號位複製到0號位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}

// 將2號位到陣列結束,複製到0號位
let i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
複製程式碼

1.5陣列例項find(),findIndex()

1.find方法:用於找出第一個符合條件的陣列成員。引數是一個回撥函式,所有陣列成員依次執行該回撥函式,知道找到第一個返回值為true的成員,然後返回該成員。find方法的回撥引數可以接受三個引數,依次為當前值、當前位置和原陣列。

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

2.findIndex方法:和find類似,返回符合條件的成員位置。

這兩個方法可以接受第二個引數,用來繫結回撥函式的this物件。

function f(v){
  return v > this.age;
}
let person = {name: 'John', age: 20};
[10, 12, 26, 15].find(f, person);    // 26
複製程式碼

可以發現NaN,彌補了indexOf方法的不足。

[NaN].indexOf(NaN)
// -1

[NaN].findIndex(y => Object.is(NaN, y))
// 0
複製程式碼

1.6陣列例項fill()

使用給定值,填充陣列

引數:

  1. value:用來填充陣列元素的值
  2. start(可選):起始索引,預設為0
  3. end(可選):終止索引,預設為this.length

如果引數只有第一個,會把陣列所有元素覆蓋,適合用於給空陣列賦初值。

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

['a', 'b', 'c'].fill(7)
// [7, 7, 7]
複製程式碼

1.7陣列例項entries(),keys(),values()

  1. 三個方法的相同點:都是用於遍歷陣列。返回一個遍歷器物件。
  2. 區別:entries遍歷鍵值對,keys遍歷鍵名,values遍歷鍵值。
console.log(...['a','b','c'].keys()); // 0 1 2
console.log(...['a','b','c'].values()); // a b c
console.log(...['a','b','c'].entries()); // [ 0, 'a' ] [ 1, 'b' ] [ 2, 'c' ]
複製程式碼
  1. 遍歷 可以用for...of迴圈遍歷,也可以手動呼叫遍歷器的next方法。
// for...of
for (let elem of ['a', 'b','c'].entries()) {
  console.log(elem);
}

// 遍歷器
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']
複製程式碼

1.8陣列例項includes()

表示陣列是否包含給定的值。

引數:

  1. valueToFind:需要查詢的元素值
  2. fromIndex(可選):從fromIndex索引處開始查詢。如果第二個引數為負數,則表示倒數的位置,如果這時它大於陣列長度(比如第二個引數為-4,但陣列長度為3),則會重置為從0開始。
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, 3].includes(3,-4); //true
[1, 2, NaN].includes(NaN); // true
複製程式碼

與Map,Set的has方法的區別:

  1. Map的has方法:查詢鍵名
  2. Set的has方法:查詢值

1.9陣列例項的flat(),flatMap()

1.flat():用於將巢狀的陣列拉平,返回一個一維陣列,對原資料沒有影響。引數:depth-指定要提取巢狀陣列的結構深度,預設值為1。如果不管有多少層巢狀,都要轉成一維陣列,可以用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]
複製程式碼

2.flatMap():首先使用對映函式對映每個元素,然後將結果壓縮成一個新陣列。

引數:

  1. callback-可以生成一個新陣列中的元素的函式,可以傳入三個引數:currentValue(當前正在陣列中處理的元素),index(可選,陣列中正在處理的當前元素的索引), array(可選,被呼叫的 map 陣列)
  2. thisArg-可選,執行 callback 函式時 使用的this值
// 相當於 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]

// flatMap只能展開一層陣列
// 相當於 [[[2]], [[4]], [[6]], [[8]]].flat()
[1, 2, 3, 4].flatMap(x => [[x * 2]])
// [[2], [4], [6], [8]]
複製程式碼

1.10陣列的空位

陣列對空位是指陣列對某一位置沒有任何值,空位不是undefined,一個位置值等於undefined仍然是有值。

ES5對空位的處理不一致,大多數情況忽略空位。ES6明確將空位轉為undefined。上述ES6新增的陣列方法都不會忽略空位。

// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]

// keys()
[...[,'a'].keys()] // [0,1]

// values()
[...[,'a'].values()] // [undefined,"a"]

// find()
[,'a'].find(x => true) // undefined

// findIndex()
[,'a'].findIndex(x => true) // 0
複製程式碼

1.11陣列常用方法(ES5的)

1.11.1 some和every方法

  1. some():測試是否==至少有一個==元素可以通過被提供的函式方法。返回Boolean型別
  2. every():測試是否==所有元素==都能通過被提供的函式方法。返回Boolean型別。

引數(兩個方法引數一致):

  1. callback-測試元素的函式,可接受三個引數:element(測試的當前值);index(可選,測試的當前值的索引);array(可選,呼叫some,every的當前陣列)
  2. thisArg-執行callback使用的this值
const hasProvider = providerList.some(item => item.providerNumber === providerNumber);

arr2.every((item, index) => item === arr1[index])
複製程式碼

1.11.2 filter方法

建立一個新陣列,其包含通過所提供函式實現的測試的所有元素。

引數(兩個方法引數一致):

  1. callback-測試元素的函式,可接受三個引數:element(測試的當前值);index(可選,測試的當前值的索引);array(可選,呼叫的當前陣列)
  2. thisArg-執行callback使用的this值
const newlist = list.filter(item => item.channelNumber === channelNumber);
複製程式碼

1.11.3 map方法

建立一個新陣列,其結果是該陣列中的每個元素都呼叫一個提供的函式後返回的結果。

引數:

  1. callback-測試元素的函式,可接受三個引數:currentValue(測試的當前值);index(可選,測試的當前值的索引);array(可選,呼叫的當前陣列)
  2. thisArg-執行callback使用的this值
const channelNumberList = channelList.map(item => item.channelNumber)
複製程式碼

1.11.4 forEach方法

對陣列的每個元素執行一次提供的函式

引數:

  1. callback-測試元素的函式,可接受三個引數:currentValue(測試的當前值);index(可選,測試的當前值的索引);array(可選,呼叫的當前陣列)
  2. thisArg-執行callback使用的this值
var array1 = ['a', 'b', 'c'];

array1.forEach(function(element) {
  console.log(element);
});
複製程式碼

1.11.5 push(), pop(), shift(), unshift()方法

1.push():將一個或多個元素新增到陣列末尾,並返回陣列新長度。

引數:elementN-被新增到陣列末尾到n個元素(按順序新增)

可以用來合併兩個陣列

var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];

// 將第二個陣列融合進第一個陣列
// 相當於 vegetables.push('celery', 'beetroot');
Array.prototype.push.apply(vegetables, moreVegs);

console.log(vegetables); 
// ['parsnip', 'potato', 'celery', 'beetroot']
複製程式碼

2.pop():刪除陣列最後一個元素,返回該元素的值。

對於空陣列使用pop方法,返回undefined。

var arr = ['a', 'b', 'c'];

arr.pop() // 'c'
arr // ['a', 'b']
[].pop() // undefined
複製程式碼

3.shift():刪除陣列第一個元素,返回該元素的值。

var a = ['a', 'b', 'c'];

a.shift() // 'a'
a // ['b', 'c']
複製程式碼

push和shift方法結合使用,構成了先進先出的佇列結構。

4.unshift():在陣列第一個位置新增元素,返回新增新元素後陣列長度。可接受多個引數。

var a = ['a', 'b', 'c'];

a.unshift('x'); // 4
a // ['x', 'a', 'b', 'c']
複製程式碼

1.11.6 join(), concat()方法

1.join():指定引數作為分隔符,將所有陣列成員連線成字串返回。不提供引數預設用逗號分隔。

var a = [1, 2, 3, 4];

a.join(' ') // '1 2 3 4'
a.join(' | ') // "1 | 2 | 3 | 4"
a.join() // "1,2,3,4"
複製程式碼

2.concat():用於多個陣列的合併,將新陣列的成員加到原陣列成員後部,==返回一個新陣列==,原陣列不變。

引數:valueN-將陣列和/或值連線成新陣列

['hello'].concat(['world'])
// ["hello", "world"]

['hello'].concat(['world'], ['!'])
// ["hello", "world", "!"]

[].concat({a: 1}, {b: 2})
// [{ a: 1 }, { b: 2 }]

[2].concat({a: 1})
// [2, {a: 1}]
複製程式碼

1.11.7 slice(), splice()方法

1.slice():提取目標陣列的一部分,返回一個新陣列,原陣列不變。

引數:

1)begin 可選 提取起始處的索引,從該索引開始提取原陣列元素,預設為 0。

如果該引數為負數,則表示從原陣列中的倒數第幾個元素開始提取,slice(-2)表示提取原陣列中的倒數第二個元素到最後一個元素(包含最後一個元素)。

如果省略 begin,則 slice 從索引 0 開始。

如果 begin 大於原陣列的長度,則會返回空陣列。

2)end 可選 提取終止處的索引,在該索引處結束提取原陣列元素,預設為 0。slice 會提取原陣列中索引從 begin 到 end。

如果該引數為負數, 則它表示在原陣列中的倒數第幾個元素結束抽取。 slice(-2,-1) 表示抽取了原陣列中的倒數第二個元素到最後一個元素(不包含最後一個元素,也就是隻有倒數第二個元素)。

如果 end 被省略,則slice 會一直提取到原陣列末尾。

如果 end 大於陣列的長度,slice也會一直提取到原陣列末尾。

var a = ['a', 'b', 'c'];

a.slice(0) // ["a", "b", "c"]
a.slice(1) // ["b", "c"]
a.slice(1, 2) // ["b"]
a.slice(2, 6) // ["c"]
a.slice() // ["a", "b", "c"]
複製程式碼

2.splice():用於刪除原陣列的一部分成員,並可以在刪除的位置新增新的陣列成員,返回值是被刪除的元素。注意,==該方法會改變原陣列==。

引數:

1)start-指定修改的開始位置(從0計數)

如果超出了陣列的長度,則從陣列末尾開始新增內容;

如果是負值,則表示從陣列末位開始的第幾位(從-1計數,這意味著-n是倒數第n個元素並且等價於array.length-n);

如果負數的絕對值大於陣列的長度,則表示開始位置為第0位。

2)deleteCount-可選,整數,表示要移除的陣列元素的個數。

如果 deleteCount 大於 start 之後的元素的總數,則從 start 後面的元素都將被刪除(含第 start 位)。

如果 deleteCount被省略了,或者它的值大於等於array.length-start(也就是說,如果它大於或者等於start之後的所有元素的數量),那麼start之後陣列的所有元素都會被刪除。

如果 deleteCount 是 0 或者負數,則不移除元素。這種情況下,至少應新增一個新元素。

3)item1, item2, ... 可選

要新增進陣列的元素,從start 位置開始。如果不指定,則 splice() 將只刪除陣列元素。

var a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.splice(4, 2, 1, 2) // ["e", "f"]
a // ["a", "b", "c", "d", 1, 2]
複製程式碼

摘自阮一峰

參考MDN

相關文章