一、ES5中创建数组
1、创建方式
// 第一种:对象字面的方式
let arr1 = [2, 4]
arr1 //[2,4]
// 第二种:new Array() / Array()的方式
let arr2 = new Array(2, 4); //<=>let arr2 = Array(2,4)
arr2 //[2,4]
2、说明:最好使用[]来创建,原因如下:
1>、先看一个演示结果
Array() //[]
Array(4) // [,,,,]
Array(2,4) //[2,4]
上面代码中,new Array() /Array()没有参数、一个参数、三个参数时, 返回结果都不一样。只有当参数个数不少于 2 个时 ,new Array() /Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定的是数组长度。
即:new Array() /Array()有个缺陷,当里面有一个值是,它代表的是对象成员的个数。而不是值。
2>、第二个原因
3、出于简洁、可读性和执行速度(发现循环次数越多,这种差别越大,new Array() / Array()输出耗时更多)的考虑。
针对上述new Array() / Array()的缺陷,ES6给出了一个新的解决方案->Array.of();
二、ES6中创建数组(将一组数据转化为数组)
let arr3 = Array.of(4);
arr3 // [4]
// Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。
三、Array.from()
可能有小伙伴有些疑惑了,既然已经新增了Array.of()这种方式, 还需要Array.from()干嘛?他们有什么区别?简单点说,
Array.from() 适用于将非数组对象转换为数组的场景,它的初衷就是为了解决将非数组对象转换为数组的问题。
具体点来说上边说的非数组对象包含这两类:类似数组(array-like object)的对象->(即伪数组)和可遍历(iterable)的对象(包括ES6
新增的Set和Map)。
1、伪数组
1>什么是伪数组?所谓的伪数组就是具有length属性,也有 0、1、2、3 等属性的对象。下面一个数据结构就是典型的伪
数组。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
2>将伪数组转换为真正的数组
// ES5的写法
let arr4 = [].slice.call(arrayLike);
arr4 // ["a", "b", "c"]
// ES6的写法
let arr5 = Array.from(arrayLike);
arr5 // ["a", "b", "c"]
3>、常见场景
实际应用中,常见的伪数组有:
DOM 操作返回的 NodeList 集合;
函数内部的arguments对象;
2、可遍历的对象(部署了Iterator接口)
1>什么是可遍历的对象?部署了Iterator接口
2>、可遍历的对象转换为真正数组
let arr6 = Array.from('hello')
arr6 // ["h", "e", "l", "l", "o"]
let namesSet = new Set(['a', 'b'])
let arr7 = Array.from(namesSet)
arr7 // ["a", "b"]
// 上面代码中,字符串和 Set 结构都具有 Iterator 接口,
// 因此可以被Array.from转为真正的数组。
3>、说明
a、扩展运算符背后调用的是遍历器接口(Symbol.iterator所以采用扩展符...也可以将可遍历的对象转化为真正的数组。
// Array.from('hello') <=> [...'hello']
b、由于伪数组中没有部署Iterator 接口,所以不能采用扩展符来进行真正数组的转换。
c、如果参数是一个真正的数组,Array.from()会返回一个一模一样的新数组。
d、Array.from()还可以接受第二个参数, 作用类似于数组的map方法,用来对每个元素进行处理, 将处理后的值放入返回的数
组。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
Array.from()可以将各种值转为真正的数组,并且还提供map功能。
3>、补充
原生具备 Iterator 接口的数据结构如下。
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象
因为它们的原型对象都拥有一个 Symbol.iterator 方法。
四、如何判断是否已经部署了iterator接口
1、代码处理:
let df = [1,2,3]
let dg = df[Symbol.iterator](); //得到遍历器对象
console.log(dg);
2、结果展示:
变量df是一个数组,原生就具有遍历器接口,部署在df的Symbol.iterator属性上面。
由结果看出,原型对象都拥有一个 Symbol.iterator 方法,说明df数组部署了iterator接口。
下面再看一个没有部署部署了iterator接口的数据结构,会显示出什么呢?
// 再看一个没有部署iterator接口的结构,伪数组
let weiArr = {
'0': 'first',
'1': 'second',
'2': 'three',
length: 3
};
let result = weiArr[Symbol.iterator]();
console.log(result);
结果:
结果看出,weiArr伪数组上没有部署iterator接口。
其他的那些需要部署,那些不需要部署,没部署的如何部署iterator接口,具体的看阮一峰老师的ES6教程:http://es6.ruanyifeng.com/#docs/iterator