ES6引進了一些新的數組方法。javascript
含義: 擴展運算符(spread)是三個點
...
,它如同rest參數的逆運算,將一個數組轉爲用逗號分隔的參數序列。
console.log(...[1, 2, 3]); // 1 2 3 console.log(1, ...[2, 3, 4], 5); //1 2 3 4 5
Rest(函數參數) 和 Spread(數組運算符) 主要是應用 ... 運算符,完成值的聚合和分解。html
// 1.rest獲得的是一個真正的數組,而不是一個僞數組。 const getOptions = function(...args){ console.log(args.join()); } const arr = [123]; getOptions(...arr); // 123 // 2.rest能夠搭配箭頭函數使用,達到取得全部參數的目的。 const getOption = (...args)=>{ console.log(args); } let arrs = [1,2,3]; getOption(...arrs); // [1,2,3] // 3.spread能夠用於解構時,聚合所得的值。 const opt1 = 'one'; const opt2 = ['two','three','four']; console.log([opt1,...opt2]); // ["one", "two", "three", "four"] //4.spread能夠用於數組定義。 const opts = ["one", "two", "three", "four"]; const config = ['other', ...opts]
該運算符主要用於函數的調用。java
function push(array, ...items){ array.push(...items); } function add(x, y){ return x + y; } const numbers = [4, 38]; console.log(add(...numbers));; // 42
從上面的代碼能夠看出,該運算符能夠將一個數組變成爲參數序列。git
function f(v, w, x, y, z){ console.log([v, w, x, y, z]); } const args = [0, 1]; f(-1, ...args, 2, ...[3]) // [-1, 0, 1, 2, 3]
擴展運算符後面放置表達式。es6
const arr = [ ...(x > 0 ? ['a'] : []), 'b', ]
若是擴展運算符後面是一個空數組,則不產生任何效果。github
console.log([...[], 1]); // [1]
替代數組的apply方法:數組
// 因爲擴展運算符能夠展開數組,因此不須要使用apply方法將數組轉爲函數的參數。 // ES5 寫法 function f(x,y,z){ console.log(x,y,z); } const args = [0,1,2]; f.apply(null,args) // 0 1 2 // ES6 寫法 function f1(x,y,z){ console.log(x,y,z); } f1(...args) // 0 1 2 // ES5 寫法 console.log(Math.max.apply(null,[14,3,77])); //77 // ES6 寫法 console.log(Math.max(...[14,3,77])); //77 //等同於 console.log(Math.max(14,3,77)); //77 // ES5 寫法 const arr1 = [0,1,2]; const arr2 = [3,4,5]; Array.prototype.push.apply(arr1,arr2); console.log(arr1); // [0, 1, 2, 3, 4, 5] // ES6 寫法 const arr11 = [0,1,2]; const arr22 = [3,4,5]; arr11.push(...arr22); console.log(arr11); // [0, 1, 2, 3, 4, 5] // ES5 寫法 console.log(new (Date.bind.apply(Date, [null , 2015, 1, 1]))); // Sun Feb 01 2015 00:00:00 GMT+0800 (中國標準時間) // ES6 寫法 console.log(new Date(...[2015, 1, 1])); // Sun Feb 01 2015 00:00:00 GMT+0800 (中國標準時間)
合併數組:數據結構
// ES5 寫法 const more = [2,2,2]; console.log([1,2].concat(more)); // [1,2,2,2,2] // ES6 寫法 console.log([1,2,...more]); // [1,2,2,2,2] // ES5 寫法 const arr1 = ['a','b']; const arr2 = ['c','d']; const arr3 = ['e','f']; const arr = arr1.concat(arr2,arr3) console.log(arr); // ["a", "b", "c", "d", "e", "f"] // ES6 寫法 console.log([...arr1,...arr2,...arr3]); // ["a", "b", "c", "d", "e", "f"] console.log([1, ...[2,3], 4]); // [1,2,3,4]
與解構賦值結合:app
// ES5 寫法 const list = [1,2]; const a = list[0]; const rest = list.slice(1); console.log(a, rest); // 1 [2] // ES6 寫法 [a1, ...rest1] = list; console.log(a1,rest1); // 1 [2] // 其餘例子 const [first,...res] = [1,2,3,4,5]; console.log(first,res); // 1 [2,3,4,5] const [first1,...res1] = []; console.log(first1,res1); //undefined [] const [first2,...res2] = ['foo']; console.log(first2,res2); // 'foo' [] const [...butLast, last] = [1,2,3,4,5] // 報錯 Rest element must be last element const [first3,...middle, last] = [1,2,3,4,5] // 報錯 Rest element must be last element
函數返回值:
JavaScript的函數只能返回一個值,若是須要返回多個值,只能返回數組或對象。擴展運算符提供瞭解決這個問題的一種變通方法。 函數
字符串:
// 將字符串轉爲真正的數組 console.log([...'hello']); // ['h','e','l','l','o'] // 正確識別32位的Unicode console.log([...'x\uD83D\uDE80y'].length); // 3
實現了Iterator接口的對象:
任何Iterator接口的對象,均可以用擴展運算符轉爲真正的數組。
對於那些沒有部署Iterator接口的相似數組的對象,擴展運算符就沒法將其轉爲真正的數組。
const arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 } // ES5 轉爲數組 const arrNew1 = [].slice.call(arrayLike); console.log(arrNew1); // ['a','b','c'] // ES6 轉爲數組 const arrNew2 = Array.from(arrayLike); // ['a', 'b', 'c'] console.log(arrNew2); // ['a', 'b', 'c'] // Uncaught TypeError: arrayLike is not iterable. const arrNew3 = [...arrayLike];
Map和Set結構、Generator函數:
// Map結構 let map = new Map([ [1,'one'], [2,'two'], [3,'three'], ]) let arr1 = [...map.keys()]; let arr2 = [...map.values()]; console.log(arr1,arr2); // [1, 2, 3] ["one", "two", "three"] // Set結構 let set = new Set([11,-1,6]); let arrNew = [...set]; console.log(arrNew); // [11,-1,6] // Generator函數 const go = function*(){ yield 1; yield 2; yield 3; } console.log([...go()]); // [1,2,3] const obj = { * [Symbol.iterator](){ yield 'a'; yield 'b'; yield 'c'; } } console.log([...obj]); // ['a','b','c'] // 對於沒有Iterator接口的對象,使用擴展運算符會報錯 const obj1 = { a:1, b:2, } console.log([...obj1]); // Uncaught TypeError: obj1 is not iterable
Array.from()
Array.from()
方法用於將兩類對象轉爲真正的數組:相似數組的對象(array-like object)和可遍歷(iterator)對象(包括ES6新增的數據結構Set和Map)。
相似數組對象轉爲數組:
let arrayLike = { '0':'a', '1':'b', '2':'c', length:3 } // ES5 寫法 let arrNew1 = [].slice.call(arrayLike); console.log(arrNew1); // ['a','b','c'] // ES6 寫法 let arrNew2 = Array.from(arrayLike); console.log(arrNew2); // ['a','b','c']
NodeList對象轉爲數組:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <p>1</p> <p>2</p> <p>3</p> <script> const ps = document.querySelectorAll('p'); Array.from(ps).forEach(function(p){ console.log(p); }) Array.from(ps).map(function(val){ console.log(val); }) Array.from(ps, x =>console.log(x)) </script> </body> </html>
arguments對象轉爲數組:
function foo(x = 0,y = 12) { let args = Array.from(arguments) console.log(args); } foo(); // [] foo(1); // [1] foo(1,2); // [1,2]
字符串(Iterator接口)轉爲數組:
console.log(Array.from('hello')); // ["h", "e", "l", "l", "o"]
Set結構(Iterator接口)轉爲數組:
let nameSet = new Set(['a','b']); console.log(Array.from(nameSet)); // ["a", "b"]
操做數組:
console.log(Array.from([1,2,3])); // [1,2,3]
相似數組的對象,特殊狀況:
console.log(Array.from({length:3})); // [undefined,undefined,undefined] console.log(Array.from({length:2},()=>'jack')); // ["jack", "jack"]
轉數組兼容性考慮:
const toArray = (()=> Array.from?Array.from:obj=>[].slice.call(obj) )();
將數組中布爾值爲false的成員轉爲0:
console.log(Array.from([1,,2,,3],(n)=>n||0)); // [1, 0, 2, 0, 3]
返回各類數據的類型:
function typesOf(){ return Array.from(arguments,value=>typeof value) } console.log(typesOf(null,[],NaN)); // ["object", "object", "number"]
避免將大於\uFFFF的Unicode字符算做兩個字符的bug:
function countSymbols(string){ return Array.from(string).length }
Array.of()
將一組值轉換爲數組,彌補數組構造函數Array的不足。
Array.of()
老是返回參數值組成的數組,若是沒有參數,就返回一個空數組。
console.log(Array.of()); // [] console.log(Array.of(undefined)); //[undefined] console.log(Array.of(null)); // [null] console.log(Array.of(1)); // [1] console.log(Array.of(1,2)); // [1,2] console.log(Array.of(3,4,7)); // [3,4,7]
Array 子類的構造函數會繼承全部的 Array 類的方法,包括 of() 方法
class MyArray extends Array { } console.log(MyArray.of(3, 11, 8) instanceof MyArray); // true console.log(MyArray.of(3).length === 1); // true
copyWithin()
會在當前數組內部制定位置的成員複製到其餘位置(會覆蓋原有成員),會返回當前數組。
Array.prototype.copyWithin(target,start=0,end=this.length)
// 將3號位到最後一位複製0號位開始日後排 let arr1 = [1,2,3,4,5] arr1.copyWithin(0,3); console.log(arr1); // [4, 5, 3, 4, 5] // 將3號位複製到0號位 let arr2 = [1,2,3,4,5] arr2.copyWithin(0,3,4); console.log(arr2); // [4, 2, 3, 4, 5] // -2至關於3號位,-1至關於4號位 let arr3 = [1,2,3,4,5]; arr3.copyWithin(0,-2,-1); console.log(arr3); // [4, 2,3 , 4, 5] // 將3號位複製到0號位 let arr4 = [].copyWithin.call({length:5,3:1},0,3); console.log(arr4); // {0: 1, 3: 1, length: 5} // 將2號位到數組結束,複製到0號位 let arr5 = new Int32Array([1,2,3,4,5]) arr5.copyWithin(0,2) console.log(arr5); // Int32Array(5) [3, 4, 5, 4, 5] // 對於沒有部署TypedArray的copyWithin方法的平臺 // 須要採用下面的寫法 let arr6 = [].copyWithin.call(new Int32Array([1,2,3,4,5]),0,3,4); console.log(arr6); // Int32Array(5) [4, 2, 3, 4, 5]
find()
和findIndex()
find()
方法用於找出第一個符合條件的數組成員。它的參數是一個回調函數,全部的數組成員依次執行該回調函數,直到找出第一個返回值爲true的成員,而後返回該成員,若是沒有符合條件的成員,則返回undefined。
findIndex
方法與find()
方法很是相似,返回第一個符合條件的數組成員的位置,若是全部成員都不符合條件,則返回-1.
let num = [1,4,-5,10].find(n=>n < 0) console.log(num); // -5 let num1 = [1,4,-5,10].find(n=>n > 11) console.log(num1); // undefined let num2 = [1,4,-5,10].findIndex(n=>n < 0) console.log(num2); // -5 let num3 = [1,4,-5,10].findIndex(n=>n > 11) console.log(num3); // -1
接受3個參數,依次爲當前的值,當前的位置和原數組:
// find返回value let num4 = [1,5,10,15].find(function(value,index,arr){ return value > 9; }) console.log(num4); // 10 //findIndex返回index let num5 = [1,5,10,15].findIndex(function(value,index,arr){ return value > 9; }) console.log(num5); // 2
將數組的空缺做爲undefined
處理:
let num6 = ['a',,'c'].find(x=>x===undefined) console.log(num6); // undefined let num7 = ['a',,'c'].findIndex(x=>x===undefined) console.log(num7); // 1
經過findIndex
方法尋找NaN
: indexOf()
一個衆所周知的侷限在於它沒法尋找NaN
.
console.log([NaN].indexOf(NaN)); // -1 console.log([NaN].findIndex(y=>Object.is(NaN,y))); // 0 // 也能夠建立輔助函數`elemIs()` function elemIs(x){ return Object.is.bind(Object, x) } console.log([NaN].findIndex(elemIs(NaN))); // 0
fill()
fill(value,start,end)
用給定的值填充數組:
console.log(['a','b','c'].fill(7)); // [7, 7, 7]
數組的空缺不會被特殊處理:
console.log(['a',,'c'].fill(7)); // [7, 7, 7] console.log(new Array(3).fill(7)); // [7, 7, 7]
限定填充範圍:
console.log(['a','b','c'].fill(7,1,2)); // ["a", 7, "c"]
keys()
、values()
和entries()
——用於遍歷數組;
——都返回遍歷器對象;
——可用for...of
遍歷;
keys()
是對鍵名的遍歷、values()
是對鍵值的遍歷、entries()
是對鍵值對的遍歷。
// `Array.from()` 把迭代器中的內容放入數組 console.log(Array.from(['a','b'].keys())); // [0, 1] console.log(Array.from(['a','b'].values())); // ['a', 'b'] console.log(Array.from(['a','b'].entries())); // [[0, 'a'], [1, 'b']] // 展開操做符(...)將迭代器轉換成數組 console.log(...['a','b'].keys()); // 0 1 console.log(...['a','b'].values()); // 'a' 'b' console.log(...['a','b'].entries()); // [0, 'a'] [1, 'b'] // `for..of`遍歷 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()
方法判斷某個數組是否包含給定的值,返回true
或者false
。
console.log([1,2,3].includes(2)); // true console.log([1,2,3].includes(4)); // false console.log([1,2,NaN].includes(NaN)); // true // 第二個參數表示搜索的起始位置,默認爲0。若是爲負數,則表示倒數的位置,若是這時大於數組的長度則會重置爲從0開始 console.log([1,2,3].includes(2,-4)); // true console.log([1,2,3].includes(2,-3)); // true console.log([1,2,3].includes(2,-2)); // true console.log([1,2,3].includes(2,-1)); // false console.log([1,2,3].includes(2,0)); // true console.log([1,2,3].includes(2,1)); // true console.log([1,2,3].includes(2,2)); // false console.log([1,2,3].includes(2,3)); // false console.log([1,2,3].includes(2,4)); // false