Array.forEach を定義してもArray汚染にはならない

Array.prototype.forEach を独自定義するとArray汚染になるが、Array.forEach ならArray汚染にならない、というお話。 「Array汚染」とは for-in でprototypeのプロパティを拾う現象のこと。 仕様通りの動作だが、prototype拡張を予期していないライブラリを利用すると不具合を誘発することがある。 続きを読む
2
think49 @think49

@think49 Array.forEach === Array.prototype.forEach.call らしい。

2010-10-18 00:06:24
think49 @think49

@think49 Array および String の汎用化 ( http://goo.gl/d62v ), Working with Array-like objects ( http://goo.gl/U87R )

2010-10-18 00:06:49
think49 @think49

@think49 Array.prototype.forEach を定義するとArray汚染になるけど、Array.forEach を拡張してもArray汚染にはならない気がする。

2010-10-18 00:11:56
think49 @think49

@think49 個人的にはArray汚染という表現が好きになれない(仕様どおりの動作なので汚染という表現に違和感あり)し、Array.prototype もどんどん拡張して良いと思う。

2010-10-18 00:14:55
テラマコ @teramako

@think49 それだと、 [].forEachは出来なくて、Array.forEach([], function() ...) にしないといけなくてちょっと冗長になってしまいますね。

2010-10-18 00:16:09
think49 @think49

@think49 ただ、表現は別として、Array汚染を気にする人は 「Array.forEach (クラスメソッド) を拡張しよう」ってことになるのかな…。

2010-10-18 00:16:59
think49 @think49

@teramako 仰るとおりだと思います。ただ、私が想定しているのは配列のようでいて配列でないオブジェクトでして、例えば、document.styleSheets や [object NodeList] などです。

2010-10-18 00:18:12
think49 @think49

@think49 この場合、Array.prototype.forEach を使えないので、結局 call することになるんですよね…。

2010-10-18 00:18:43
テラマコ @teramako

@think49 あー、なるほど。了解です。

2010-10-18 00:20:30
think49 @think49

@think49 Array.prototype.forEach.call(document.getElementsByTagName('p'), callbackfn); と書くなら、Array.forEach() の方がちょっぴり短く書けます。

2010-10-18 00:21:05
shogo ohta @os0x

@think49 クロスブラウザを考えなくても良いケースなら、NodeListにメソッドを追加するというネタも http://gist.github.com/403594

2010-10-18 00:36:24
think49 @think49

@os0x 実行してみました。NodeList.prototype に Array.prototype のメソッドをコピーするんですね。面白いなあ。

2010-10-18 00:50:48
think49 @think49

@think49 Array.forEach, Array.some を拡張する方針で更新してみた。 http://gist.github.com/630663

2010-10-18 00:51:27