美文网首页
JavaScript中的ES6迭代器

JavaScript中的ES6迭代器

作者: 魂斗驴 | 来源:发表于2021-04-01 09:14 被阅读0次

我们将在本文中分析Iterators。迭代器是一种遍历JavaScript中任何Set的新方法。它们是在ES6中引入的,并已变得非常流行自从 它们广泛有用,并在各个地方使用。

我们将在概念上理解什么是迭代器以及在示例中将其使用在何处。我们还将看到它在JavaScript中的一些实现。

介绍

假设您有这个数组-

const myFavouriteAuthors = [
  'Neal Stephenson',
  'Arthur Clarke',
  'Isaac Asimov', 
  'Robert Heinlein'
];

在某个时候,您将需要取回数组中的所有单个值,以便在屏幕上打印它们,对其进行操作或对它们执行某些操作。如果我问你,你会怎么做?您会说-这很容易。我就对他们循环中使用forwhilefor-of或一个这些循环的方法。 示例实现为—

数组上的各种循环技术

现在,假设您有一个自定义数据结构来容纳所有作者,而不是前面的数组。像这样 -

自定义数据结构

现在,myFavouriteAuthors是一个包含另一个object的对象allAuthorsallAuthors包含三个阵列,对应key是fictionscienceFictionfantasy现在,如果我要您遍历myFavouriteAuthors所有作者,您的做法是什么? 您可以继续尝试一些循环组合以获取所有数据。

但是,如果您这样做-

for (let author of myFavouriteAuthors) { 
  console.log(author)
}
// TypeError: {} is not iterable

你会得到一个TypeError说法,那就是对象是不可迭代的让我们看看什么是可迭代的,以及如何使对象可迭代的。 在本文的最后,您将了解如何for-of在自定义对象(在本例中为on)上使用循环myFavouriteAuthors

可迭代和迭代器

您在上一节中看到了问题。没有简单的方法可以从我们的自定义对象中获取所有作者。我们需要一种方法,通过该方法可以顺序公开所有内部数据。

让我们添加一个方法getAllAuthorsmyFavouriteAuthors返回所有作者。像这样 -

getAllAuthors实现

这是一种简单的方法。它完成了我们当前吸引所有作者的任务。但是,此实现可能会出现一些问题。他们之中有一些是 -

  • 这个名字getAllAuthors很具体。如果别人创造了自己的myFavouriteAuthors名字,他们可以给它命名retrieveAllAuthors
  • 作为开发人员,我们始终需要了解将返回所有数据的特定方法。在这种情况下,它名为getAllAuthors
  • getAllAuthors返回所有作者的字符串数组。如果另一个开发人员以这种格式返回对象数组怎么办?
[ {name: 'Agatha Christie'}, {name: 'J. K. Rowling'}, ... ]

开发人员将必须知道返回所有数据的方法的确切名称和返回类型

如果我们制定一个规则来确定方法的名称及其返回类型 将是固定且不可更改的,该怎么办?

我们将此方法命名为– iteratorMethod

ECMA采取了类似的步骤来标准化循环遍历自定义对象的过程。但是,iteratorMethodECMA使用名称代替了名称Symbol.iteratorSymbols提供的名称是唯一的,并且不能与其他属性名称冲突。同样,Symbol.iterator返回一个称为iterator的对象 。此迭代器将具有称为的方法next,该方法将返回带有键value和的对象done

value密钥将包含当前值。它可以是任何类型。的done是布尔值。它表示是否已获取所有值。

图解可以帮助建立关系iterables迭代器,和next这种关系称为迭代协议。

可迭代,迭代和下一步之间的关系。

  • 一个迭代是想让它的元素向公众开放的数据结构。它是通过实现一个key为Symbol.iterator的方法来实现的。该方法是迭代器的工厂。也就是说,它将创建迭代器
  • 一个迭代器是用于遍历数据结构的元素的指针。

使objects可迭代

因此,正如我们在上一节中了解到的那样,我们需要实现一种称为Symbol.iterator的方法。我们将使用计算属性语法来设置此键。一个简短的例子是-

image.png

可迭代的例子

在第4行,我们进行迭代。这是一个已next定义方法的对象。该next方法根据step变量返回值。在第25行,我们检索iterator。我们于27日致电next。我们一直打电话给下一位,直到done成为true

这正是for-of循环发生的情况。该for-of循环需要一个迭代,并创建它的迭代器。它一直在调用next()直到直到done为真。

JavaScript中的可迭代

JavaScript中有很多事情是可迭代的。它可能不会立即可见,但是如果仔细检查,可迭代项将开始显示。

这些都是可迭代的-

  • 数组TypedArrays
  • 字符串-遍历每个字符或Unicode代码点。
  • Map-遍历其键值对
  • Set-遍历其元素
  • arguments —函数中类似数组的特殊变量
  • DOM元素

JS中使用可迭代对象的其他一些构造是-

  • for-of循环-在for-of循环需要一个迭代。否则,它将抛出TypeError
for (const value of iterable) { ... }
  • 数组的解构—因为可迭代,所以发生解构。让我们看看如何。

代码

const array = ['a', 'b', 'c', 'd', 'e'];
const [first, ,third, ,last] = array;

相当于

const array = ['a', 'b', 'c', 'd', 'e'];
const iterator = array[Symbol.iterator]();
const first = iterator.next().value
iterator.next().value // Since it was skipped, so it's not assigned
const third = iterator.next().value
iterator.next().value // Since it was skipped, so it's not assigned
const last = iterator.next().value
  • 解构运算符(…)

代码

const array = ['a', 'b', 'c', 'd', 'e'];
const newArray = [1, ...array, 2, 3];

可以写成

const array = ['a', 'b', 'c', 'd', 'e'];
const iterator = array[Symbol.iterator]();
const newArray = [1];
for (let nextValue = iterator.next(); nextValue.done !== true; nextValue = iterator.next()) {
  newArray.push(nextValue.value);
}
newArray.push(2)
newArray.push(3)
  • Promise.allPromise.race在Promises上接受可迭代项。
  • Map和Set

Map的构造函数将可迭代的over[key, value]对转换为Map,而Set的构造函数将可迭代的over元素转换为Set-

const map = new Map([[1, 'one'], [2, 'two']]);
map.get(1) 
// one
const set = new Set(['a', 'b', 'c]);
set.has('c');
// true
  • 迭代器也是了解生成器功能的前提。

使myFavouriteAuthors可迭代

这是一个myFavouriteAuthors可迭代的实现。

const myFavouriteAuthors = {
  allAuthors: {
    fiction: [
      'Agatha Christie', 
      'J. K. Rowling',
      'Dr. Seuss'
    ],
    scienceFiction: [
      'Neal Stephenson',
      'Arthur Clarke',
      'Isaac Asimov', 
      'Robert Heinlein'
    ],
    fantasy: [
      'J. R. R. Tolkien',
      'J. K. Rowling',
      'Terry Pratchett'
    ],
  },
  [Symbol.iterator]() {
    // Get all the authors in an array
    const genres = Object.values(this.allAuthors);
    
    // Store the current genre and author index
    let currentAuthorIndex = 0;
    let currentGenreIndex = 0;
    
    return {
      // Implementation of next()
      next() {
        // authors according to current genre index
        const authors = genres[currentGenreIndex];
        
        // doNotHaveMoreAuthors is true when the authors array is exhausted.
        // That is, all items are consumed.
        const doNothaveMoreAuthors = !(currentAuthorIndex < authors.length);
        if (doNothaveMoreAuthors) {
          // When that happens, we move the genre index to the next genre
          currentGenreIndex++;
          // and reset the author index to 0 again to get new set of authors
          currentAuthorIndex = 0;
        }
        
        // if all genres are over, then we need tell the iterator that we 
        // can not give more values.
        const doNotHaveMoreGenres = !(currentGenreIndex < genres.length);
        if (doNotHaveMoreGenres) {
          // Hence, we return done as true.
          return {
            value: undefined,
            done: true
          };
        }
        
        // if everything is correct, return the author from the 
        // current genre and incerement the currentAuthorindex
        // so next time, the next author can be returned.
        return {
          value: genres[currentGenreIndex][currentAuthorIndex++],
          done: false
        }
      }
    };
  }
};

for (const author of myFavouriteAuthors) {
  console.log(author);
}

console.log(...myFavouriteAuthors)

可迭代的示例实现

利用从本文中获得的知识,您可以轻松地了解迭代器的工作方式。该逻辑可能有点难以遵循。因此,我已经用代码编写了注释。但是,内化和理解该概念的最佳方法是在浏览器或节点中使用代码。

参考

A Simple Guide to ES6 Iterators in JavaScript with Examples

相关文章

  • Javascript 迭代器是什么

    Javascript 迭代器是什么 JavaScript迭代器是在ES6中引入的,用于循环一系列值,通常是某种集合...

  • es6基础知识3(迭代)

    title: es6基础知识3(迭代)tags: 迭代categories: 前端 1. 迭代器 es6中新增了迭...

  • JavaScript中的ES6迭代器

    我们将在本文中分析Iterators。迭代器是一种遍历JavaScript中任何Set的新方法。它们是在ES6中引...

  • 迭代器,生成器和yield

    迭代器, 生成器, yield 都是ES6 中的新语法 迭代器 迭代器由三个方法组成: hasNext() 是否还...

  • ES6 迭代器(Iterator)和 for...of循环使用方

    一、什么是迭代器? 生成器概念在Java,Python等语言中都是具备的,ES6也添加到了JavaScript中。...

  • ECMAScript6-in-depth学习笔记

    ECMAScript 6 (ES6)JavaScript属于ES的扩展。 第二章·迭代器和for-of循环 1、E...

  • JavaScript设计模式-0001---迭代器模式

    使用闭包实现迭代器 test es6使用 生成器实完成迭代器模式 使用es6的生成器实现数据自增 迭代器/es6的...

  • [Decorator] 学习

    # Javascript 中的装饰器 # ES6 系列之我们来聊聊装饰器

  • es6-迭代器和生成器

    迭代器 一个迭代器对象 ,知道如何每次访问集合中的一项, 并跟踪该序列中的当前位置。在 JavaScript 中...

  • Generator(一)

    要理解生成器,先理解迭代器。因为生成器就是返回一个迭代器的函数。 ES5实现的迭代器 ES6中的生成器用法: 生成...

网友评论

      本文标题:JavaScript中的ES6迭代器

      本文链接:https://www.haomeiwen.com/subject/amcthltx.html