参考书《ECMAScript 6入门》
http://es6.ruanyifeng.com/

数组的扩展

1.扩展运算符:可以将数组转化成逗号隔离的单个参数
...[1,2,3] //控制台运行报错
console.log(...[1,2,3]);//1,2,3

(1)代替apply方法
function test(a,b){return a+b;}
test.apply(null,[1,2]) 同 test(...[1,2]) 作用一样
(2)复制数组
var arr1 = [1,2,3],var arr2 = [];
arr2 = arr1.concat();
arr2 = [...arr1] 或 [...arr2] = arr1 //同样可达到复制数组的效果
改变arr2的值也不会影响到arr1
(3)合并数组
将arr2追加到arr1的尾部
var arr1 = [1,2,3],arr2 = [4,5,6],arr3;
Array.prototype.push.apply(arr1,arr2); 同 arr1.push(...[arr2]);作用一样
arr3 = [...arr1,...arr2] //[1,2,3,4,5,6]
(4)与解构赋值结合来赋值
[a,...b] = [1,2,3,4,5] // a---1, b---->[2,3,4,5]
(5)将字符串转为数组
let str = "word";
console.log(...str);//['w','o','r','d']
还可以识别unicode编码超过\uFFFF 需要用四个字节表示的字符 var str = "asdc𠮷";console.log([...str].length) //5 "𠮷"是一个四字节的字符,str.length = 6 不准确,错把四字节字符判断成两个字符,[...str].length更准确

(6)可以将有Iterator接口的对象转化为数组,如nodelist
var nodes = document.querySelectorAll('div');
[...nodes] //转化为节点数组
Map,Set数据结构和Generator函数都有迭代器接口,可以使用扩展运算符

数组实例方法的扩展
(1)Array.prototype.from:可以将类数组对象和带有Iterator接口的对象转化成数组
类数组对象:必须要有length属性,Array.from转化时会把空位认为是undefined。如果length值与属性个数不对应,多于属性个数的的值是undefiend,少于属性个数的部分都被去掉。
var obj = {
  0 : "n1",
  1 : "n2",
  2 : "n3",
  length : 3
}
Array.from(obj) //["n1", "n2", "n3"]
[].slice.call(obj) //["n1", "n2", "n3"]
带有Iterator接口的对象:常见的如dom树,可以通过Array.from转成数组
var nodes = document.querySelectorAll('div');
Array.from(nodes);

(2)Array.of()总是返回由参数组成的数组,如果没有则返回空数组
Array.of(3) //[3]
new Array(3) //[,,,]
Array.of({"n1" : 1},{"n2" : 2},{"n3" : 3})//[{"n1" : 1},{"n2" : 2},{"n3" : 3}]
(3)Array.prototype.copyWithin : 将指定位置的数组成员赋值到其他位置(覆盖原位置成员),返回当前数组。
有三个参数,第一个代表开始替换数据的位置,第二个代表开始读取的位置(包括),第三个代表结束读取的位置(不包括)
[1,2,3,4,5,'m',6,7,8,9,0].copyWithin(0,6,11) //[6, 7, 8, 9, 0, "m", 6, 7, 8, 9, 0]
(4)Array.prototype.find与Array.prototype.findIndex
相同点:都可以接受两个参数,第一个参数是回调函数,第二个参数可以是一个对象,用来为第一个参数回调函数提供this;
        第一个参数是回调函数,此回调函数可以有三个参数,第一个是当前的数组元素值,第二个是当前元素的下标值,第三个参数是一个数组。
不同点:find用于找出第一个满足要求的数组成员,如果没有满足条件的,则返回undefined。
        findIndex用于找出第一个满足要求的数组成员的位置下标,如果没有满足条件的,则返回-1。

[1,2,3,4,5].find(function(v,i,arr){v = v+2;arr = [];arr.push(v);console.log(i);console.log(arr)})
0 [3]
1 [4]
2 [5]
3 [6]
4 [7]

[1,2,3,4,5].findIndex(function(v,i,arr){return v === 5});
//4 数组元素5的下标

(5)Array.prototype.fill 用于填充数组
    可以接受三个参数,第一个是要填充的值,第二个是填充开始的位置(包括),第三个是填充结束的位置(不包括,填充在此前结束)。
   如果只传第一个参数,不指定第二第三个位置参数,则原有数组的值全部会被新的填充值取代。
   生成数组元素为0的长度为10的数组
   Array.from({length:0}).fill(0)//[0,0,0,0,0,0,0,0,0,0]
   使用fill像数组中填充新对象或者新数组时,不是深拷贝
  let array = Array.from({length:3}).fill({"name" : "test"})
  //array   (3) [{name: "test"}, {name: "test"}, {name: "test"}]
  array[0].name = "thisone" //改变第一个元素的属性值
  //array   (3) [{name: "thisone"}, {name: "thisone"}, {name: "thisone"}]
  array[0] = {"name" : "thattwo"} //整个赋值
  //array   (3) [{name: "thattwo"}, {name: "thisone"}, {name: "thisone"}]

(6)Array.prototype.keys //对键名进行遍历,返回遍历器对象
(7)Array.prototype.values //对值进行遍历,返回遍历器对象
(8)Array.prototype.entries//对整个键值对进行遍历,返回遍历器对象
var arr = [1,2,3,4,5];
for(let k of arr.keys()){
  console.log(k);//0 1 2 3 4
}
for(let v of arr.values()){
  console.log(v);//1 2 3 4 5
}
for(let entry of arr.entries()){
  console.log(entry);//[0,1] [1,2] [2,3] [3,4] [4,5]
}

(9)Array.prototype.includes 用于判断数组是否包含某元素,是则返回true,否则返回false
   有两个参数,第一个参数值要判断是否存在的值,第二个表示判断开始的位置(此参数如果为负,则倒数开始)
(10)Array.prototype.indexOf 用于判断数组是否包含某元素,如果存在,返回此元素在数组中的下标,如果不存在,则返回-1
   [NaN].indexOf(NaN) // -1
   [NaN].includes(NaN) //true  includes方法更准确直观

(3)空位
  所有ES6新定义的数组实例的方法都会将空位处理成undefined
  Array.from({length:3}) //[undefined,undefined,undefined]
  var arr = [,,];
  for(let c of arr.keys()){console.log(c)} // 0 1
  for(let c of arr.values()){console.log(c)} // undefined undefined