- 迭代器Iterator
表示集合的数据结构:数组和对象(js定义的)、Map和Set(Es6新增的)。如何访问这些不同的数据结构呢,Es6提供了一个统一的管理接口,就是迭代器Iterator,也就是只要部署遍历器(Iterator),就可以完成遍历操作。 - 迭代器Iterator的作用
一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是 ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。 - 遍历器Iterator属性:Symbol.iterator
具有这个属性的数据结构都有可遍历性。 - 原生具备 Iterator 接口的数据结构如下。
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象
*对象没有原生的遍历器属性,对象(Object)之所以没有默认部署 Iterator 接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。不过,严格地说,对象部署遍历器接口并不是很必要,因为这时对象实际上被当作 Map 结构使用,ES5 没有 Map 结构,而 ES6 原生提供了。 - 怎样给不具有遍历器的对象,类数组添加遍历器属性
1.对象
一个对象如果要具备可被for…of循环调用的 Iterator 接口,就必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)。
2.类数组
ex:NodeList.prototype[Symbol.iterator]=Array.prototype[Symbol.iterator];
let iterable = {
0: ‘a’,
1: ‘b’,
2: ‘c’,
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // ‘a’, ‘b’, ‘c’
} - 默认调用itertor接口
(1)解构赋值
对数组或者set数据结构进行解构时:
var arr=[‘a’,‘b’]
var [x,y]=arr;
x=“a”;
y=“b”;
var arr =new set().add(‘a’).add(‘b’).add(‘c’);
var [x,…y]=arr;
x=‘a’;y=[‘b’,‘c’]
(2)扩展运算符
string arr=“dsafsa”
[…arr]=[‘d’,‘s’,‘a’,‘f’,‘s’,‘a’]
只要某个数据结构部署了 Iterator 接口,就可以对它使用扩展运算符,将其转为数组。
(3)yield*
(4)其他场合
for…of
Array.from()
Map(), Set(), WeakMap(), WeakSet()(比如new Map([[‘a’,1],[‘b’,2]]))
Promise.all()
Promise.race() - 计算生成的数据结构
- entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用entries方法。
- keys() 返回一个遍历器对象,用来遍历所有的键名。
- values() 返回一个遍历器对象,用来遍历所有的键值。
注意 :使用for…in 和for…of的区别
- 循环方法对比
for循环比较麻烦
forEach比较简单,但是不能中途停止
for…in 主要是为对象设计,也可遍历数组的键名,但是遍历的键名是字符串。
for…of是最好的方法,能解决上面都没有的问题