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循环访问。
-
Stringvar 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); } -
Arrayvar 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); } -
Setvar 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..offor (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新特性内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复