prototypeの汚染と, その対策
こんにちは. 昨日のエントリのコメントで「for-inで列挙されないようにすべき」とご指摘をいただきました. それについてのまとめ.
問題
以下のようにprototype拡張を行った場合, for-in文で列挙すると拡張をおこなったプロパティも表示される.
プログラム
Array.prototype.test = function () {}; var hoge = ['a', 'b', 'c']; for (var i in hoge) { console.log(i); }
結果
0 1 2 test
配列はfor文を使うのでは
しかし, 配列を拡張する場合に限っては気にする必要はないと思う. なぜなら, 配列をfor-in文で列挙することはないから. 普通は以下のようにfor文で走査する.
Array.prototype.test = function () {}; var hoge = ['a', 'b', 'c']; for (var i = 0; i < hoge.length; i++) { console.log(hoge[i]); }
どうしてもfor-in文を使う場面がきても
どうしてもfor-in文を使うときがきても, hasOwnProperty()メソッドで防げる. for-in文を使うときはhasOwnPropery()メソッドを必ず伴うべきと「JavaScript the good parts」や「JavaScript patterns」でプラクティスとして紹介されている.
Array.prototype.test = function () {}; var hoge = ['a', 'b', 'c']; for (var i in hoge) { if (hoge.hasOwnProperty(i)) { console.log(i); } }
まとめ
配列はfor文で走査し, もしfor-in文でプロパティを列挙するときはhasOwnProperty()メソッドを伴うようにする.
ただ, 指摘いただいた通り, 無闇にpropertyを拡張するのはよくないと思う. とくにチームで開発するときはメンバーの了解を必ずとるべきだし, プラクティスの共有を日頃から行うべきだと感じました.