Array, from()
将类数组对象和可遍历对象转化为真正的数组。数组
var arrayLike = { '0' : 'a', '1' : 'b', '2' : 'c', 'length': 3 } var arr; //ES5 arr = [].slice.call(arrayLike); //arr=['a', 'b', 'c'] //ES6 arr = Array.from(arrayLike); //arr=['a', 'b', 'c']
和它相似的是扩展运算符, 同样能够实现该功能(要求对象具备遍历器接口):babel
function(){ var arg = [...arguments]; //转化 arguments 为数组 }
Array.from() 接受第二参数(函数), 用来映射结果, 至关于 map, 而且能够用第三个参数绑定 this:ide
Array.from(obj, func, context); //等价于 Array.from(obj).map(func, context);
技巧, 用 Array.from() 指定函数运行次数:函数
var i = 0; Array.from({length: 3}, ()=>i++); //[0, 1, 2]
建议:使用Array.from方法,将相似数组的对象转为数组。this
Array.of()
将多个值组成数组:prototype
Array.of(2, 3, 5); //[2, 3, 5] Array.of(2); //[2] Array.of(); //[] Array.of(undefined); //[undefined]
Array.prototype.copyWithin()
函数参数是 Array.prototype.copyWithin(target, start=0, end=this.length)
, 对当前数组, 从截取下标为 start 到 end 的值, 从target 位置开始覆盖 this
中的值。若是 start 或 end 为负数则倒数。翻译
[1, 2, 3, 4, 5].copyWithin(0, 3, 4); //[4, 2, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(0, -2, -1); //[4, 2, 3, 4, 5] [].copyWithin.call({length: 5, 3: 1}, 0, 3); //{0: 1, 3: 1, length: 5} var i32a = new Int32Array([1, 2, 3, 4, 5]); i32a.copyWithin(0, 2); //[3, 4, 5, 4, 5]
Array.prototype.find()
, Array.prototype.findIndex()
这两个函数的参数都是回调函数。遍历数组, 找到符合条件(回调函数返回为true)的第一个值, find()返回其值, findIndex()
返回其下标。若是没找到符合条件的值find()
返回undefined, findIndex()
返回-1。code
[1, 2, -3, 4].find((item) => item < 0); //-3 [1, 2, -3, 4].findIndex((item) => item < 0); //2 [NaN].findIndex(y => y !== y); //0 [NaN].indexOf(NaN); //-1, indexOf 找不到 NaN
这两个函数还接受第二参数, 用来绑定回调函数中的 this对象
Array.prototype.fill()
完整形式: Array.prototype.fill(value, start=0, end=this.length)
, 对数组 start 到 end 直接部分填充 value, 覆盖原有值。索引
[1, 2, 3, 4, 5].fill('a', 2, 4); //[1, 2, 'a', 'a', 5]; var arr = new Array(5).fill(0); //arr = [0, 0, 0, 0, 0];
Array.prototype.entries()
, Array.prototype.keys()
, Array.prototype.values()
这三个方法, 用来遍历数组, 返回一个遍历器, 供 for...of
使用, 其中 keys()
是对键的遍历, values()
是对值的遍历, entires()
是对键值对的遍历。babel 已实现
var a = ['a', 'b', 'c']; for(let item of a.values()){ console.log(item); //依次输出 'a', 'b', 'c' } for(let key of a.keys()){ console.log(key); //依次输出 0, 1, 2 } for(let pair of a.entries()){ console.log(pair); //依次输出 [0, 'a'], [1, 'b'], [2, 'c'] }
固然也能够用遍历器的 next() 方法遍历
var a = ['a', 'b', 'c']; var values = a.values(); console.log(values.next().value); //'a' console.log(values.next().value); //'b' console.log(values.next().value); //'c'
Array.prototype.includes()
这是个 ES7 的方法, 判断数组中是否含有某个值, 含有则返回 true, 不然返回 false。能够用第二个参数指定查找起始点(小于0倒数)。
//该方法一样能够找到 NaN, 而 indexOf 不行 [1, 2, NaN].includes(NaN); //true [1, 2, 3, 4, 5].includes(2, 3); //false
咱们比较如下两个数组:
var empty = new Array(3); //[, , , ] var unempty = new Array(3).fill(undefined); //[undefined, undefined, undefined] console.log(0 in empty); //false console.log(0 in unempty); //true
结合手册内容以下就很好理解这个问题:
“Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by
an AssignmentExpression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the
Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array,
that element does not contribute to the length of the Array.”
摘自 ECMAScript® 2015 Language Specification
翻译以下。
"数组成员能够省略。只要逗号前面没有任何表达式,数组的length属性就会加1,而且相应增长其后成员的位置索引。被省略的成员不会被定
义。若是被省略的成员是数组最后一个成员,则不会致使数组length属性增长。”
很明显, 一个彻底空的数组是没有东西的, 而填充了undefined
的数组并非空的。
结合 ES5, 发现不一样函数方法对空位处理方式是不同的:
forEach()
, filter()
, every()
, some()
会忽略空值map()
, copyWithin()
会保留空值, 但不作处理join()
, toString()
, 会把空值处理为空字符串fill()
不区分空值与非空值Array.from()
, 扩展运算符(...), for...of
, entires()
, keys()
, values()
, find()
, findIndex()
会视空值为 undefined
若是你记不住这些, 或者为了程序的健壮性, 可维护性, 尽可能避免在数组中出现空值。
举个实例, 理解一下这个问题:
新建一个长为200的数组, 并初始化每一个位置的值等于其索引
//错误方法 var arr = new Array(200).map(function(item, index){ return index; }); console.log(arr); //[undefined × 200]
//正确作法 var arr = new Array(200).join().split(',').map(function(item, index){ return index; }); console.log(arr); //[1, 2, 3, ..., 200]
这是一个 ES7 的功能, 暂时还没能实现。咱们能够先看一下它如何推导的:
var a1 = [1, 2, 3, 4]; var a2 = [for( i of a1) i * 2]; //a2=[2, 4, 6, 8]
不难看出, 数组 a2 经过 for...of
直接从 a1 生成。可是它的功能不单单这么简单, 还能够有 if 条件:
var a1 = [1, 2, 3, 4]; var a3 = [for( i of a1) if(i > 2) i * 2]; //a3=[6, 8]
这样, 咱们能够简单的用数组推导模拟 map()
, filter()
方法了。好比上面2个例子等价于:
var a1 = [1, 2, 3, 4]; var a2 = a1.map( (i) => i * 2 ); var a3 = a1.filter( (i) => i > 2 ).map( (i) => i * 2 );
固然咱们还能够用多个 for...of
构成循环嵌套:
var a = ['x1', 'x2']; var b = ['y1', 'y2']; [for(i of a) for(j of b), console.log(i+', '+j)]; //输出 //['x1', 'y1'] //['x1', 'y2'] //['x2', 'y1'] //['x2', 'y2']
数组推导由 []
构建了一个做用域, 其内部新建的变量, 等同于用 let 关键字声明的变量。除此以外, 字符串也能够被视为数组, 因此一样可使用数组推导:
[for(c of 'abcde'). c+'.'].join(''); //"a.2.3.4.5."