js之Iterator

迭代器的应用

数据处理:汇总下面对象中的数字

let a = {
    b: {
        c: [
            '1',
            '2',
            '3'
        ],
        d: [
            '4',
            '5',
            '6',
            '7'
        ],
        e: [
            '8',
            '9',
            '10'
        ]
    }
}

// 这里不能使用for...of,是由于Object的prototype上没有[Symbol.iterator]方法,故会报错
for (let o of a) {
  console.log(o)
}
// Uncaught TypeError: authors is not iterable

如果想遍历该对象,一是可以改变数据格式

for (let key in a) {
  let r = []
  for (let k in a[key]) {
    r = r.concat(a[key][k])
  }
  console.log(r)
}
// ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

二是通过自定义Iterator 接口,使其可遍历

a[Symbol.iterator] = function () {
    let b = this.b
    let keys = Reflect.ownKeys(b)
    let values = []
    return {
        next () {
            if (!values.length) {
                if (keys.length) {
                    values = b[keys[0]]
                    keys.shift()
                }
            }
            return {
                done: !values.length,
                value: values.shift()
            }
        }
    }
}

// 定义了[Symbol.iterator]接口后,就可以被for...of迭代了
for (let o of a) {
  console.log(o)
}

可迭代协议

如果让一个对象是可遍历的,就要遵守可迭代协议,该协议要求
1.对象要部署一个以 Symbol.iterator 为 key 的键
2. Symbol.iterator 的值就是一个要遵守迭代器协议的无参函数

迭代器协议

迭代器协议要求符合以下条件:
1.一个对象需包含一个无参函数 next
2.next 返回值也是一个对象,包含 done 和 value 属性。其中 done 表示遍历是否结束,value 返回当前遍历的值。

具备默认Iterator 接口的数据类型

ES6 的有些数据结构原生具备 Iterator 接口(比如数组),即不用任何处理,就可以被for…of循环遍历。原因在于,这些数据结构原生部署了Symbol.iterator属性:

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

Generator和Iterator

Generator 天然满足可迭代协议,利用 Generator 就不再需要显示的写迭代协议了(因为Generator包含next方法和包含 done、value 属性的返回对象)。

// 用generator改写上面的迭代器接口函数:
a[Symbol.iterator] = function * () {
    let b = this.b
    let keys = Reflect.ownKeys(b)
    let values = []
    while (1) {
        if (!values.length) {
            if (keys.length) {
                values = b[keys[0]]
                keys.shift()
                yield values.shift()
            } else {
                return false
            }
        } else {
        yield values.shift()
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值