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