ES6新特性 Iterator和for..of循环 刺骨的言语ヽ痛彻心扉 2022-02-19 23:51 162阅读 0赞 ## `Iterator` ## * `Iterator`是ES6引入的一种新的遍历机制,迭代器有两个核心概念: * 迭代器是一个统一的借口,他的作用是使各种数据结构可被便捷地访问。 迭代器是通过一个键位`Symbol.iterator`的方法来实现。 * 迭代器是用于遍历数据结构元素的指针(类似于数据库中的游标`cursor`)。 * 迭代过程 1. 获取迭代器(指向当前数据结构的起始位置)。 * 通过`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`。 1. 多次调用`iterator.next()`向下迭代指向下一个位置。 * `next()`方法会返回当前位置的对象,然后指针后移。 * 对象的格式:`{value: [...], done: 布尔值}`,其中 * `value`: 当前元素的值的数值。`Map`的为`[key, value]`,其他的`value`一般长度为1。 * `done`: 判断遍历是否结束(是否移动到了最后一个元素)。 1. 当`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种)和使用(增删改查)][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进行遍历 [JS_Map_7]: https://blog.csdn.net/wuyujin1997/article/details/88739311
还没有评论,来说两句吧...