我可以用一个简单的函数创建一个迭代器吗? (没有生成器或Symbol.iterator) [英] Can I make an iterator with a simple function? (No generator or 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 constantSymbol.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屋!