【问题标题】:Node.js Iterator interfaceNode.js 迭代器接口
【发布时间】:2014-03-31 03:25:30
【问题描述】:

我正在阅读 Iterators and generators 上的 MDN 指南,并实现了以下示例:

function Range(low, high){
  this.low = low;
  this.high = high;
}
Range.prototype.__iterator__ = function(){
  return new RangeIterator(this);
};

function RangeIterator(range){
  this.range = range;
  this.current = this.range.low;
}
RangeIterator.prototype.next = function(){
  if (this.current > this.range.high)
    throw StopIteration;
  else
    return this.current++;
};

var range = new Range(3, 5);
for (var i in range) {
  console.log(i);
}

但我明白了:

low
high
__iterator__

它应该返回的地方:

3
4
5

是否可以在 Node.js 中按预期实现?

注意:我使用的是node --harmony myscript.js

** 编辑 **

我还应该注意,我知道__iterator__Mozilla-feature only。我想知道 Node.js 中的等价物是什么。或者下一个最好的事情是什么。

另外,我想为此使用生成器,因为我希望迭代没有任何条件测试。

我的结论是唯一的等价物是

Range.prototype.each = function (cb) {
  for (var i = this.low; i <= this.high; i++) {
     cb(i);
  }
};

//...
range.each(function (i) {
  console.log(i);
});

有其他选择吗?

【问题讨论】:

    标签: javascript node.js iterator


    【解决方案1】:

    是的。

    生成器和迭代器是 ECMAScript 6 / JavaScript 1.7 的一部分。 Node 支持它们,但您需要在启动脚本时激活它们。

    例如:

    node --harmony_generators --harmony_iteration your_script.js
    

    查看blog post 了解更多信息。

    【讨论】:

    • 如果您查看标志,我已指定我正在使用--harmony 功能...我在问题中添加了通知。
    • @YanickRochon 当我输入我的答案时,编辑就在那里。但这很重要,显然这没有帮助。
    • @YanickRochon 看起来像是在最新但不稳定的 node.js 版本中添加的生成器。你确定使用 node.js 的 0.11.x 分支吗?
    • 恕我直言,这个问题与生成器无关。我已经在使用生成器,一切正常。问题不在于那里; Mozilla 实现了 Node.js 尚不支持的Object.prototype.__iterator__,我想知道在 Node.js 中是否有可能;意味着以 for (var key in obj) 不返回对象的属性,而是返回迭代器的值的方式实现对象的原型。
    【解决方案2】:

    我认为你的代码有一个错误,你写了for (var i in range) 而不是for (var i of range)in 关键字打印出对象的属性,您想使用 of 来实际获取迭代器值。

    无论如何,自从提出问题以来,Node.js 现在有了更好的和谐支持。这是一个更新的代码示例,它在 Node 4.2 上开箱即用。 __iterator__ 名称已更改为 Symbol.iterator,并且未使用 StopIteration 异常。

    "use strict";
    
    function Range(low, high){
      this.low = low;
      this.high = high;
    }
    Range.prototype[Symbol.iterator] = function(){
      return new RangeIterator(this);
    };
    
    function RangeIterator(range){
      this.range = range;
      this.current = this.range.low;
    }
    RangeIterator.prototype.next = function(){
      let result = {done: this.current > this.range.high, value: this.current};
      this.current++;
      return result;
    };
    
    var range = new Range(3, 5);
    for (var i of range) {
      console.log(i);
    }
    

    【讨论】:

    • 实际上,我刚刚在 Node 4.0 中测试了您的代码,它确实可以开箱即用没有 --harmony 标志。 :) 当您编辑答案以修复这些细节时,我会选择它作为这个问题的解决方案。谢谢!
    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 2010-11-25
    • 2012-11-07
    • 2014-08-13
    • 2012-07-06
    • 2011-05-05
    • 2014-04-18
    • 1970-01-01
    相关资源
    最近更新 更多