※そもそもPrototype汚染をやめる、という話は別の機会に。
汚染された状態でも for in文を書きたい人向けです。
プロトタイプ汚染とは
Object.prototype.myMethod を拡張すると、
for in ループで myMethod が(意図せず)列挙されてしまいます。これが汚染です。
[参考][プロトタイプ汚染とループ]
(http://uupaa.hatenablog.com/entry/2012/11/07/143947)
汚染対策
①for inをやめる:Object.Keys
※for in文の書き方とか言っておきながら、いきなりやめます(`・ω・)☆
for inをやめると、汚染されたプロトタイプ拡張で追加された
methodを呼び出すことはなくなります。わぁい。
というわけで、**Object.Keys**を使います。
Object.keys(obj).forEach(function (p) {
//do something
})
これで連想配列を安全に振り回せます。
ただし、これは、EcmaScript5で策定されたものです。
対象ブラウザ:http://kangax.github.io/compat-table/es5/#Object.keys
IE9から/(^o^)\
サポートブラウザをIE9としていたとしても
心の底では出来る限りサポートブラウザを増やしたい。。。。
②for inをやめたくない時:hasOwnProperty
※①をそう簡単に出来ないという場合(本題)
IE7とか8もまだサポートしたい\( 'ω')/ウオオオオアアアアーーーーーッ!!!となったら…
毎回if文を書きたくない場合はもうすこし考えます…
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
//do something
}
}
他にもいろいろあるみたい。
prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法
いちいちhasOwnPropertyを使わなくてよくする(ジェネレータの使いかた)
まとめ
- 軽い気持ちのprototype拡張は汚染を招く
- 考えての拡張は汚染じゃない。汚染じゃないからやっても良い
- というかES5からは拡張しても安全になりつつある
- ES5の関数を使うならIE8,7は切ろう
- 汚染が起きても大丈夫なようにfor inを使うならhasOwnPropertyなどを使おう
- もしくはObject.Keysを使う
- hasOwnPropertyとObject.Keysで一部違いがあるのはちゃんと把握していた方が良さそう
for-inとObject.keysの違いを正しく知る
→実装のパターンなどがあるので時間があるとき読むと◎です