我可以用一个简单的函数创建一个迭代器吗? (没有生成器或Symbol.iterator) [英] Can I make an iterator with a simple function? (No generator or Symbol.iterator)

查看:168
本文介绍了我可以用一个简单的函数创建一个迭代器吗? (没有生成器或Symbol.iterator)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用普通函数创建一个迭代器,没有生成器或使用 Symbol.iterator 协议用于学术目的。为此,我创建了一个函数,它返回一个带有 next 参数的对象,但是尝试将其作为 iterable 对于循环的的参数会产生不需要的结果。

I have been trying to make an iterator using a plain function, without a generator or using the Symbol.iterator protocol for academic purposes. For that, I have made a function that returns an object with a next parameter, but trying to run it as the iterable argument of an for...of loop yields unwanted results.

这是我到目前为止的代码,我从 MDN上的迭代器和生成器页面

Here is my code so far, which I copied from the Iterators and Generators page on MDN:

function iterateThis(arr){
    let i = 0;
    return {
        next: function() {
            return i < arr.length ?
                {value: arr[i++], done: false} :
                {done: true};
        }
     };
}

如果我尝试像这样运行它:

If I try to run it like so:

const iterable = iterateThis([1,2,3,4,5]);
for(item in iterable){
    console.log(item);
}

在控制台上,我得到一个结果:下一步

On the console, I just get a single result: next.

我在创建函数 iterateThis 时做错了什么? 的仅用于生成器和 Symbol.iterator 属性?

Am I doing something wrong in the creation of the function iterateThis? Or is for...of only designed to work with generators and the Symbol.iterator property?

在Node v8.11.1上执行

Executed on Node v8.11.1

推荐答案

问题是你的 iterateThis 函数返回迭代器但是构造的需要 iterable

The problem is that your iterateThis function returns an iterator but the for/of construct expects a iterable.

好的,等等,差异是什么?

来自 MDN关于迭代协议的页面


为了可迭代,对象必须实现 @@ iterator
方法,意味着对象(或其
原型链中的一个对象)必须具有带 @@ iterator 键的属性,这是
可通过常量 Symbol.iterator

In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator:

另一方面:


实现<$时,对象是迭代器 c $ c> next()带有
语义的方法:由于长度而导致Ommited,TL; DR:下一个方法
返回一个形式的对象: {value:T,done:boolean}

An object is an iterator when it implements a next() method with the following semantics: Ommited due to length, TL;DR: The next method returns an object of the form: {value: T, done: boolean}

他们相关的是调用 iterable @@ iterator 方法返回迭代器

They are related in that calling the @@iterator method of an iterable returns an iterator.

/ code>循环的总是需要一个可迭代的,所以如果你想使用 for / of ,你必须使用 @@ iterator / Symbol.iterator 。据我所知,它没有办法绕过它。但是,当你的 Symbol.iterator 方法被调用时,只需创建一个返回迭代器的对象,就可以很容易地修改你的代码段来使用它:

The for/of loop always expects an iterable, so if you want to use for/of, you have to use @@iterator/Symbol.iterator. There's just no way around it as far as I know. But your snippet can be easily modified to use it by just creating an object that returns your iterator when it's Symbol.iterator method is called:

function iterateThis(arr){
    let i = 0;
    return {
        next: function() {
            return i < arr.length ?
                {value: arr[i++], done: false} :
                {done: true};
        }
     };
}

function makeIterableFromIterator(iterator) {
  return {
    [Symbol.iterator]: function() {
      return iterator;
    }
  }
}

const iterator = iterateThis([1, 2, 3, 4, 5]);
const iterable = makeIterableFromIterator(iterator);

for (item of iterable) {
  console.log(item);
}

这篇关于我可以用一个简单的函数创建一个迭代器吗? (没有生成器或Symbol.iterator)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆