現状のFirefox,Chromeで、for-of でイテレートできるようにする

Firefox 26.0a1 (Nightly)

  • @@iterator 実装なし
    • 代わりに iterator メソッドを定義するとOK(仕様外)
    • __iterator__ というものもあるが、for-of とは無関係(独自実装)
  • GeneratorObject の next メソッドは値を返すのみで{ done: ..., value: ... }な値を返さない(仕様違反)
var iterObj = {
  iterator: function * () {
    for (var i = 0; i < 5; ++i) {
      yield i;
    }
  },
}
for (var v of iterObj) {
  console.log(v);
  // 0
  // 1
  // 2
  // ...
}

Chrome 31 (Canary)

  • @@iterator 実装なし
  • next メソッドを備えたオブジェクトがイテレート可能と見なされる(そんな仕様なし)
var iterObj = {
  value: 0,
  next: function () {
    var v = this.value++;
    return {
      done: v > 5,
      value: v
    };
  },
}

for (var v of iterObj) {
  console.log(v);
  // 0
  // 1
  // 2
  // ...
}

統合する

var iterObj = {
  value: 0,
  iterator: function * () {
    for (var res = this.next(); !res.done; res = this.next()) {
      yield res.value;
    }
  },
  next: function () {
    var v = this.value++;
    return {
      done: v > 5,
      value: v
    };
  },
};

現状だと、Chrome の next に合わせて作るのが良さそうではある。

が、仕様外であり、修正が面倒。一方、iterator メソッドは動きとしては @@iterator と同じであり、今後メソッド内部を変更する必要がない。...けれども、こちらを基準に作ると next メソッドが書きにくい。

どっちもどっちで、現状はクソな感じ。