素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: twitter: @javascripter にどうぞ。

Arrayにfor..in、for eachを使っても順序が保証されるようにする(__iterator__)

Array.prototype.__iterator__ = function(isKey) {
  var self = this;
  return (isKey ? i[0] : i[1] for (i in new Iterator(self)));
};

for(var i in [1, 2, 3])
  console.log(i); // 0, 1, 2

これで、Arrayに対しても安心してfor..inを使うことができる。

あと、XPathResultのprototypeに

XPathResult.prototype.__iterator__ = function(){
  switch(this.resultType){
  case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
  case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
    for(let i = 0;i < this.snapshotLength;i++)
      yield this.snapshotItem(i);
    break;
  case XPathResult.FIRST_ORDERED_NODE_TYPE:
    yield this.singleNodeValue;
    break;
  case XPathResult.STRING_TYPE:
    yield this.stringValue;
    break;
  case XPathResult.NUMBER_TYPE:
    yield this.numberValue;
    break;
  case XPathResult.BOOLEAN_TYPE:
    yield this.booleanValue;
    break;
  case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
  case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
    for(let i;i = this.iterateNext();)
      yield i;
    break;
  }
};

というものを追加しておくと、

for(
  var i in 
  document.evaluate(
    "descendant::a",
    document,
    null,
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null))
  console.log(i);

みたいにできてかなり便利なのだけど、yieldはGreasemonkeyとかから使えないのが残念。yield使わないとかなり面倒臭い(Iteratorを無理矢理使ったり、ジェネレーター式を無理に使ったりしないとできない)。