迭代是什么?

本文深入解析迭代器与可迭代对象的概念,探讨其在JavaScript中的应用,包括String、Array、Map、Set等内置可迭代对象的特点,以及如何自定义迭代器。同时,对比可迭代与可枚举的差异,通过实例演示不同遍历方式。

经常看到迭代这个词,那么归总下吧~

什么是 可迭代对象

一个对象(或它的原型链上的某个对象)必须有一个名字是 Symbol.iterator的属性

  • String Array Map Set 是内置可迭代的对象,因为它们的原型对象都有一个 @@iterator 方法
  • Object 不是
接收可迭代对象的API

数组的遍历 会调用迭代器接口,所以使用到数组作为参数的场合,都使用了遍历器

  • Map([iterable]) WeakMap([iterable])
  • Set([iterable]) WeakSet([iterable])
  • Promise.all([iterable]) Promise.race([iterable])
  • Array.from([iterable])
  • for...in for...of
  • getOwnPropertyNames

不能用 for...in 来迭代 Set, 因为 Set 中的元素没有 key, 使用 for...of 遍历

迭代器 与 迭代对象的差别:

迭代器是一种特殊的对象,每一个迭代器都有一个 next(),该方法返回一个对象,包括 valuedone 属性

    // 实现一个返回迭代器对象的函数
    function createIterator(items){
        var i = 0;
        return {
          next () {
                var done = (i >= items.length);
                var value = !done ? items[i++] : 'undefined'
                return {
                    done,
                    value
                }
            }
        }
    }
    const a = createIterator([1, 2, 3]);   
    //该方法返回的最终是一个对象,包含value、done属性。
    console.log(a.next()); //{value: 1, done: false}
    console.log(a.next()); //{value: 2, done: false}
    console.log(a.next()); //{value: 3, done: false}
    console.log(a.next()); //{value: undefined, done: true}
可迭代 和 可枚举的差别
举例说明 不可迭代
let arrayLike = {
  0: 'aa',
  1: 'bb',
  2: 'cc',
  length: 3
}

for (var item of arrayLike) {
  console.log(item) // TypeError: arrayLike is not iterable
}

let obj = {
  a: 'monday',
  b: 'sunday'
}

for (var item of obj) {
  console.log(item) // TypeError: obj is not iterable
}

上面这个例子是想遍历一个 类数组对象 和 一个 对象, 因为它不可迭代,所以用 for...of不能遍历
报错TypeError: arrayLike is not iterable

但是使用 for...in 又可以遍历了

for (var item in arrayLike) {
  console.log(item) // 0 1 2 length
}

for (var item in obj) {
  console.log(item) // a b 
}

这是为什么呢?

附上阮一峰老师的解释

对象(Object)之所以没有默认部署Iterator接口,是因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定。本质上,遍历器是一种线性处理,对于任何非线性的数据结构,部署遍历器接口,就等于部署一种线性转换。不过,严格地说,对象部署遍历器接口并不是很必要,因为这时对象实际上被当作Map结构使用,ES5没有Map结构,而ES6原生提供了。

以及知乎上的解答为什么for...of对象不可迭代---贺师俊回调 , 写的很棒,一下就清晰了~

// 几种迭代方式
for (const k of Object.keys(obj)) ... // enumerable own keys
for (const [k, v] of Object.entries(obj)) ... // enumerable own [key, value]s
for (const k of Object.getOwnPropertyNames(obj)) // all own keys
for (const s of Object.getOwnPropertySymbols(obj)) // all own symbols
for (const k of Reflect.ownKeys(obj)) // all own keys (include symbols)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值