资讯专栏INFORMATION COLUMN

简单学习遍历器Iterator

Xufc / 1916人阅读

摘要:遍历器之后数据结构除了数组和对象,又添加了和。遍历器是一种接口规格,任何数据结构只要部署这个接口,就可以完成遍历操作提供了一个指针,通过指针的指向进行遍历操作它提供了一个指针,默认指向当前数据结构的起始位置。

遍历器iterator

ES6之后数据结构除了数组和对象,又添加了Map和Set。遍历器是一种接口规格,任何数据结构只要部署这个接口,就可以完成遍历操作

提供了一个指针,通过指针的指向进行遍历操作

它提供了一个指针,默认指向当前数据结构的起始位置。也就是说,遍历器返回一个内部指针,
第一次调用next方法,将指针指向第一个成员,第二次调用next方法,指针指向第二个成员

下面是一个模拟遍历器指针的例子

function makeIterator(array) {
  let nextIndex = 0
  return {
      next: function() {
          return (nextIndex < array.length) ? {value: array[nextIndex++], done: false} : {value: undefined, done: true}
      }
  }
}

let it = makeIterator(["a", "b"])
it.next() // {value: "a", done: false}
it.next() // {value: "b", done: false}
it.next() // {value: "undefined", done: false}

遍历器是一个对象,具有next方法,调用next方法,就可以遍历事先给定的数据结构

Iterator接口的目的,就是为所有的数据结构提供一种统一的访问机制,就是for of循环

默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说数据结构具有该属性就可以认为是可遍历的

有三类数据结构原生具备了Iterator接口:数组、类数组对象、Set和Map,可以直接使用for of方法
而对象需要在Symbol.iterator的属性上部署遍历器方法,才可以for of

下面是通过遍历器实现指针结构的例子

// 在原型链上部署System.iterator方法,调用该方法,会返回遍历器对象iteator。调用该对象的next方法,在返回一个值的同时,自动将内部指针指向下一个实例
function test (value) {
    this.value = value
    this.next = null
}

test.prototype[Symbol.iterator] = function () {
    let iterator = {
        next: next // iterator.next是一个function
    }

    let current = this
    
    function next () {
        if (current) {
            let value = current.value
            let done = current == null
            current = current.next
            return {
                value: value,
                done: done
            }
        } else {
            return {
                done: true
            }
        }
    }   
    return iterator
}

let one = new test(1),
    two = new test(2),
    three = new test(3);

one.next = two
two.next = three

for (let i of one) {
    console.log(i) // 1 2 3
}

还有一种简单操作,对于类数组对象

NodeList.prototypoe[Symbol.iterator] = Array.prototype[Symbol.iterator]

默认调用iterator接口的场合

解构赋值

扩展运算符

yield*

Arrat.from()

Map和Set

部署Symbol.iterator最简单实现是结合Generator

let myIterable = []
myiIterable[Symbol.iterator] = function* () {
    yield 1
    yield 2
    yield 3
}
[...myIterable] // [1, 2, 3]

// 或者
let obj = {
    * [Symbol.iterator]() {
        yield "hello"
        yield "world"
    }
}
for (let x of obj) {
    console.log(x) // hello world
}

而对于对象来说,是不能直接使用for of的,需要使用yield包装以下

// 以下情况报错
let e = {
    a: 1,
    b: "bbb"
}

for (let [key, value] of e) {
    console.log() // error,e is not iterable
}

// 使用yield包装一下
function* (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

JavaScript 原有的 for...in 循环,只能获得对象的键名,不能直接获取键值。ES6 提供 for...of 循环,允许遍历获得键值。

var arr = ["a", "b", "c", "d"];

for (a in arr) {
  console.log(a); // 0 1 2 3
}

for (a of arr) {
  console.log(a); // a b c d
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88446.html

相关文章

  • 从贺老微博引出的“遍历Iterators)加速那些奥秘”

    摘要:我关注的贺老贺师俊前辈最近发表个这样一条微博虽然这条微博没有引起大范围的关注和讨论,但是作为新人,我陷入了思考。通过贺老的微博,对一个问题进行探究,最终找到核心成员的一文,进行参考并翻译。 我关注的贺老—贺师俊前辈@johnhax 最近发表个这样一条微博: showImg(https://segmentfault.com/img/remote/1460000010452807); 虽然...

    XUI 评论0 收藏0
  • JavaScript 设计模式(五):迭代模式

    摘要:文章内容分两部分前半部分为迭代器模式概念后半部分为中迭代器上半部分开始迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。下半部分开始的迭代器迭代器等同于遍历器。执行该函数,会返回一个遍历器对象。 showImg(https://segmentfault.com/img/bVbuyaZ?w=800&h=600); 文章内容分两部分: 前半部分为 迭...

    zhou_you 评论0 收藏0
  • 当谈论迭代时,我谈些什么?

    摘要:示例代码如下此示例中可以看出,当迭代器终止时,通过抛出异常告知迭代器已耗尽。但如果迭代器所指向的数据结构在其存在时发生了插入或删除操作,则迭代器将可能失效。与的情形类似,对进行任何插入操作也将损坏迭代器。 花下猫语:之前说过,我对于编程语言跟其它学科的融合非常感兴趣,但我还说漏了一点,就是我对于 Python 跟其它编程语言的对比学习,也很感兴趣。所以,我一直希望能聚集一些有其它语言基...

    王军 评论0 收藏0
  • java的集合和泛型的知识点归纳1

    摘要:接口也是集合中的一员,但它与接口有所不同,接口与接口主要用于存储元素,而主要用于迭代访问即遍历中的元素,因此对象也被称为迭代器。迭代器的实现原理我们在之前案例已经完成了遍历集合的整个过程。 【Collection、泛型】 主要内容 Collection集合 迭代器 增强for 泛型 教学目标 [ ] 能够说出集合与数组的区别 [ ] 说出Collection集合的常用功能 [ ]...

    daryl 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<