Iterator与for...of小结

Iterator与for...of小结

技术杂谈小彩虹2021-07-15 8:53:4490A+A-

1. 背景

ES6 借鉴 C++、Java、C# 和 Python 语言,引入了for...of循环,作为遍历所有数据结构的统一的方法。

一个数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口,就可以用for...of循环遍历它的成员。也就是说,for...of循环内部调用的是数据结构的Symbol.iterator方法。

即,Iterator就是一个遍历接口。

2. 目前已实现iterator的数据类型

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

以Array为例:

const arr = ['a', 'b', 'c', 'd']
for (const value of arr) {
    console.log(value) // a b c d 
}

image.png

3. Iterator实现原理

引用官方的表达:

image.png

判断结束就是返回的数据对象中的done为true。 // {done: true, value: undefined}

4. Object类型如何创建Iterator遍历接口

4.1 方案一:Generator封装

从文章第三章可以发现,其实底层就是Generator函数, 我们用Generator包一下

jsconst obj = { a: 1, b: 2, c: 3 }

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

for (let [key, value] of entries(obj)) {
  console.log(key, '->', value);
}
// a -> 1
// b -> 2
// c -> 3

4.2 方案二:借用数组的Iterator

Array对象是具备可迭代的,但前提是key值为数组的下标,这类对象是比较极端的,不是通用做法,仅用来开拓思路。

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'
}

4.3 方案三:自定义Iterator方案

既然我们制定for...of是通过一次次调用next方法来获取每一次轮训的值

let obj = {
    a:1,
    b:2,
    [Symbol.iterator](){
        let index = 0;
        return {
            next: () => {
                let keys = Object.keys(this);
                return index >= keys.length ? {done: true} : {value: this[keys[index++]]}
            }
        }
    }
};
for (let val of obj) {
    console.log(val);// 1, 2
}

5. 遍历api小结

数组对象为例

5.1 for循环

1.使用功能最全,是最原始的遍历写法。 2.写起来比较不舒服,比较麻烦。所以数组对象提供了forEach和map方法

5.2 forEach/map

1.数组全变量遍历,api轻巧。 2.循环无法中途退出,return和break命令皆不奏效

5.3 for...in

1.api轻巧、方便。 2.for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。for...in本意是为遍历对象设计。

5.4 for...of

1.api轻巧、方便。 2.可以配合continue、break、return使用,灵活度较高 3. 前提是该遍历类型已经实现Iterator接口

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们