New in JavaScript 1.7 - MDC
あれれ。Generatorが使えるようになってるじゃあないか。それならPythonみたいにNodeListを扱えるかと思って、次を試してみた。
NodeList.prototype.items = function(){
    for (let i=0, len=this.length; i<len; i++) {
         yield this.item(i);
    }
};
var nl = document.getElementsByTagName("P");
for each(let elm in nl.items()) {
    alert(elm.textContent);
}
これならfor eachでNodeListを扱うときに余計な判別式を使わなくてすむ。と思いきや何故かnl.itemsがundefined。nl instanceof NodeListはtrueなのにね。まあ実装方法はこうでなくてもいいわけで、とりあえずGeneratorの動作を確認すべく再試行した。
var nl = document.getElementsByTagName("P");
for each(let elm in NodeList.prototype.items.apply(nl)) {
    alert(elm.textContent);
}
ちなみにJavascript1.7のにゅーフィーチャー「destructuring assignment」を使うとさらにPythonicなスクリプトが書けるよ。
var nl = document.getElementsByTagName("P");
for each(let {textContent: c, attributes: a} in NodeList.prototype.items.apply(nl)) {
    let s = "";
    for each(let {name: n, value: v} in NodeList.prototype.items.apply(a)) {
        s += n + " = " + v + "\n";
    }
    s += c;
    alert(s);
}
prototypeチェインが繋がらないのが謎だけど、チェインに拘らなければ別に気にならない。そもそも上の例ではprototypeチェインでitemsジェネレータを繋ごうとすると、継承関係のないNamedNodeMapとNodeListそれぞれに同じことをしなければならない(まあできないんだけど)。だったらクラスメソッドにでもしておいた方が良いのかも。
4.4. Doing something for every HTML element [Dive Into Greasemonkey]
NodeListは「生きて」いるのでlengthプロパティはgetterを呼ぶ。これではforループで毎回呼び出すことになるだろう。しかもgetElementsByTagName("*")でその回数は膨大。今まではlengthプロパティの「値」を参照する代案を提示してきたが、Greasemonkey scriptということでJavascript1.6が使える前提で例を。
var allElements, thisElement;
allElements = document.getElementsByTagName('*');
for each (thisElement in allElements) {
	if (!(thisElement instanceof Element)) continue;
	// do something with thisElement;
}
参照:Core JavaScript 1.5 Reference - MDC