ES6之Array.of()、Array.from()与iterator迭代器

一、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

发布了32 篇原创文章 · 获赞 57 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/Syleapn/article/details/98639373