最初の例:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { console.log(i); // prints both bar and moo }
ここでは 2 つの点に注意する必要があります。まず、for in ループは false に設定された enumerable 属性を無視します。たとえば、配列の長さプロパティです。 2 つ目は、for in はプロトタイプ チェーン全体を走査するため、プロトタイプ チェーンが長すぎるとパフォーマンスに影響を与えることです。
Enumerable は非常に馴染みのない単語ですが、実際には JavaScript ではその影をほとんど見つけることができず、実際には作者が Ruby から借用したものです。 enumerable を作成する目的は、enumerable を単独で使用するのではなく、「混合」して使用することです。Prototype の多くのメソッドは、enumerable を混合して使用するため、プロトタイプの基本と言えます。ここでは詳しい紹介はしません。詳細については、「Enumerable」を参照してください。
for in ループ自体の動作を変更することはできないため、「JavaScript 学習ノート - オブジェクト (3): hasOwnProperty」を通じて、他のメソッドを使用してループ内に表示したくないプロパティを除外することしかできません。 》hasOwnProperty メソッドでこれができることがわかっています。
hasOwnProperty フィルターを使用します
前の例を引き続き使用します:
// Poisoning Object.prototype Object.prototype.bar = 1; var foo = {moo: 2}; for(var i in foo) { if (foo.hasOwnProperty(i)) { console.log(i); } }
これが唯一の正しい書き方です。hasOwnPropertyメソッドを使用しているため、今回はmooのみが出力されます。 hasOwnPropertyメソッドが適用できない場合、Object.prototypeの拡張時にエラーが発生します。
現在、多くのフレームワークは Object.prototype からメソッドを拡張することを選択しているため、これらのフレームワークを使用するときに、hasOwnProperty でフィルターされていない for ループを使用すると問題が発生します。
概要
ネイティブ プロトタイプ オブジェクトが拡張されているかどうかに関係なく、実行環境について何も仮定しないで、hasOwnProperty を使用してプロパティをフィルタリングする良い習慣を身に付けることをお勧めします。