【问题标题】:Adding a custom iterator to a javascript class将自定义迭代器添加到 javascript 类
【发布时间】:2013-10-15 21:12:03
【问题描述】:

我试图弄清楚如何将迭代器添加到 javascript 类中,以便可以在 for...in 循环中使用该类。遵循 Mozilla 的指示并不会产生他们声称的结果。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators 给定示例的 Jsfiddle:http://jsfiddle.net/KQayW/

function Range(low, high){
  this.low = low;
  this.high = high;
  this.current = low;
  this.next = function() {
    if (this.current > this.range.high)
      throw StopIteration;
    else
      return this.current++;
  }
}
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++;
};
Range.prototype.__iterator__ = function(){
  return new RangeIterator(this);
};
var range = new Range(3, 5);
for (var i in range)
  document.getElementById("test").innerHTML = i+"</br>"; // prints 3, then 4, then 5 in sequence

它不会打印出范围内的数字,它会打印出“__iterator__”!

有谁知道如何让它工作?

【问题讨论】:

    标签: javascript iterator for-in-loop


    【解决方案1】:

    Mozilla 文档指出迭代器功能是在 JavaScript 1.7 中引入的。尽管 Chrome 支持 1.7 中的某些功能,但它并未完全受支持,因此这不起作用。如果你在最新的 Firefox 版本中测试你的代码,你会发现它可以工作。

    虽然您可能想要附加范围值而不是替换整个 div。

    http://jsfiddle.net/KQayW/2/

    function Range(low, high){
      this.low = low;
      this.high = high;
      this.current = low;
      this.next = function() {
      if (this.current > this.range.high)
        throw StopIteration;
      else
        return this.current++;
      }
    }
    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++;
    };
    Range.prototype.__iterator__ = function(){
      return new RangeIterator(this);
    };
    var range = new Range(3, 5);
    for (var i in range)
      document.getElementById("test").innerHTML += i+"</br>"; // prints 3, then 4, then 5 in sequence
    

    【讨论】:

      【解决方案2】:

      使用 ES2015 很简单:

      function Range(start, end) {
          var ret = {};
          ret[Symbol.iterator] = function *() {
              while (start < end) 
                  yield start++;
          }
          return ret;
      }
      

      虽然你必须使用:

      for (var x of Range(1, 10))
      

      【讨论】:

      • 但是有什么方法可以在不使用生成器语法的情况下做到这一点?
      【解决方案3】:

      使用 ES2015 可以更简单

      const Range = (start, end) => ({
        *[Symbol.iterator]() {
          while (start < end) 
              yield start++;
        }
      })
      
      for (var x of Range(1, 10)) {
        console.log(x)
      }

      【讨论】:

        【解决方案4】:

        或者你也可以不使用生成器语法。如果您想了解迭代器的工作原理,这可能会有所帮助。

        function range(start, end) {
            return {
                [Symbol.iterator]() {
                    return this;
                },
                next() {
                    return start <= end ? {value: start++} : {done: true};
                }
            };
        }
        
        console.log(...range(1, 10));

        range() 函数返回一个“可迭代对象”。 可迭代对象是可迭代的,因为它有一个函数[Symbol.iterator](),它返回一个“迭代器对象”。 迭代器对象是一个迭代器,因为它有一个next() 函数。

        在这种情况下,iterable 和 iterator 是同一个对象,这简化了它。

        【讨论】:

          猜你喜欢
          • 2013-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-04
          • 1970-01-01
          相关资源
          最近更新 更多