将自定义迭代器添加到 JavaScript 类

Adding a custom iterator to a javascript class

本文关键字:JavaScript 添加 自定义 迭代器      更新时间:2023-09-26

我正在尝试弄清楚如何将迭代器添加到javascript类中,以便该类可以在...循环中。遵循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__"!

有谁知道如何让它工作?

使用 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))

使用ES2015可以更简单

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

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

或者你可以在没有生成器语法的情况下做到这一点。如果您试图了解迭代器的工作原理,这可能会有所帮助。

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()函数。

在这种情况下,可迭代对象

和迭代器是同一个对象,这简化了它。