概述
Iterator
-
Iterator
是ES6引入的一种新的遍历机制,迭代器有两个核心概念:- 迭代器是一个统一的借口,他的作用是使各种数据结构可被便捷地访问。
迭代器是通过一个键位Symbol.iterator
的方法来实现。 - 迭代器是用于遍历数据结构元素的指针(类似于数据库中的游标
cursor
)。
- 迭代器是一个统一的借口,他的作用是使各种数据结构可被便捷地访问。
-
迭代过程
- 获取迭代器(指向当前数据结构的起始位置)。
- 通过
Symbol.iterator
创建迭代器。- 可迭代对象:
iterable
- 其迭代器:
iterable[Symbol.iterator]()
,(String, Array, Set, Map)通用。 - 可返回其迭代器的方法:
iterator[Symbol.iterator]
- 可迭代对象:
- 通过对象的某些方法返回迭代器对象。如:
-
arr.values()
-
set.keys(), set.values()
-
map.keys(), map.values(), map.entries()
-
String
对象没有实例方法用于返回其迭代器对象,所以只能用Symbol.iterator
。
-
- 多次调用
iterator.next()
向下迭代指向下一个位置。
next()
方法会返回当前位置的对象,然后指针后移。- 对象的格式:
{value: [...], done: 布尔值}
,其中value
: 当前元素的值的数值。Map
的为[key, value]
,其他的value
一般长度为1。done
: 判断遍历是否结束(是否移动到了最后一个元素)。
- 当
done
为true
时遍历结束。
如要重新迭代,需要重新获取迭代器
(从第1步重新开始)。
可迭代的数据结构
String
Array
Set
Map
DOM元素(开发中。。。)
for..of
其中:for (let e of obj) { console.log(e); }
e
- 可以直接为
e
- 也可以是具体每个元素的value形式如
map
队形的[key, value]
。
- 可以直接为
obj
- 可以直接是对象本身(如
map
) - 也可以是对象的迭代器
iterator
(如map.keys(), map.values(), map.entries(), map[Symbol.iterator]()
)。
- 可以直接是对象本身(如
不同搭配,性能可能会有所差异。
- 两种方式迭代访问可迭代数据解构
iterator.next()
for..of
迭代访问
以下依次为String, Array, Set, Map
类对象的 迭代器访问和 for…of循环访问。
-
String
var str = "hello"; var iterator = str[Symbol.iterator](); for (let i = 0; i < str.length; i++) { console.log(i, iterator.next().value); // 或value[0],因为此时value数组只有一个元素。 } // for (let ch of str[Symbol.iterator]) { for (let ch of str) { // 也可以是str console.log(ch); }
-
Array
var arr = Array.from("abcd"); var iterator = arr.values(); // 返回Array Iterator对象 for (let i = 0; i < arr.length; i++) { console.log(i, iterator.next().value); // 或value[0] } // arr或arr.values()或arr[Symbol.iterator]皆可。 for (let e of arr) { console.log(e); }
-
Set
var set = new Set().add("a").add("b").add("c"); // 链式调用 var iterator = set[Symbol.iterator](); for (let i = 0; i < set.size; i++) { console.log(i, iterator.next().value); // 或value[0] } // set, set.keys(), set.values(), set[Symbol.iterator]皆可。 for (let e of set) { console.log(e); }
-
Map
Map
类对象除了可以用map[Symbol.iterator]()
获取其迭代器MapIterator
。
Map
类对象有3种成员方法也可以获取(针对其元素不同位置的)迭代器:map.keys()
map.values()
map.entries()
另外,也可通过map[Symbol.iterator]()
获取其迭代器MapIteraor。 **NOTE**
mapSymbol.iterator相当于
map.entries(),同时遍历元素的
key-value`对。
遍历方式同上,唯一不同的是map.entries()
返回的迭代器的next()
方法返回的对象:
{value: [key, value], done: 布尔值}
中,value
为长度为2的数组。
var map = new Map().set(1, "one").set(2, "two");
var iterator = map.entries();
undefined
for (let i = 0; i < map.size; i++) {
console.log(i, iterator.next().value)
}
// 两种for..of循环
for (let entry of map) {
console.log(entry);
}
for (let [key, value] of map) {
console.log(key, value);
}
JS中Map对象的创建,遍历(7种)和使用(增删改查)
NOTE
- 函数内的隐式参数
arguments
其实是Array
类型,所以也用迭代器迭代。 for..of
for (e of obj)
中的e
可以用关键字var, let, const
声明。var
迭代不会每次都创建一个新的存储空间,但全局有效(for..of
循环外e
依旧可用)let, const
每次迭代创建一个新的存储空间,但可以保证作用域的迭代内部。
且用const
声明的话,e
值不可修改。
object
不可迭代
可迭代的数据结构有:String, Array, Set, Map
不可迭代的有:Object
,以及ES6新增的WeakSet, WeakMap
(未定义obj[Symbol.iterator]()
)。arrayLike
类数组对象
因为object
无法被迭代。
但是有一种特殊对象,其属性名称中只有一个length
(属性值为数值类型),其他属性名称都是数值,类似于数组的索引(0, 1, 2, 3
等)。
这种对象可以用Array.from(obj)
转换为数组对象,然后就可以对数组进行迭代。
var arrayLike = {length: 4, 0:"zero", 1:"one", 3:"four"}; // Object
var arr = Array.from(arrayLike); // Array
console.log(arr);
// (4) ["zero", "one", undefined, "four"]
之后就可以对新得到的数组arr进行遍历
最后
以上就是深情母鸡为你收集整理的ES6新特性 Iterator和for..of循环的全部内容,希望文章能够帮你解决ES6新特性 Iterator和for..of循环所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复