2012-10-04 7 views
51

可能性の重複:
How do I check to see if an object has a property in Javascript?このfor..inとhasOwnPropertyを

私はTwitterのJSファイルで次のコードを発見しました。私はなぜ 'dict'が 'key'プロパティを持っているのを見るためにhasOwnProperty関数を呼び出す必要があるのだろうと思っていましたか? 'dict'に 'key'があることを意味する 'dict'の各 'key'に対してforループが実行されていますが、ポイントがありませんか?

function forEach(dict, f) { 
    for (key in dict) { 
     if (dict.hasOwnProperty(key)) 
      f(key, dict[key]); 
    } 
} 
+3

ここでよく説明されています:http://stackoverflow.com/a/136411/27512 – kevingessner

+0

「key」のように見えますが、このコードはどこにありますか、そこにリンクを投稿できますか? – elclanrs

+0

@elclanrs私は間違っていました。このコードはChromeのutils.js – scusyxx

答えて

54

そうでない場合、それは(おそらくネイティブオブジェクトのプロトタイプをいじって誰かによって追加された)について、あなたは知っていないものも含めプロトタイプチェーン上のすべてのプロパティをループ、になるため。

この方法では、オブジェクトインスタンス自体にあるキーだけが保証されます。

+0

ありがとうございます。今、もっと意味がある。 – scusyxx

5

javascriptの上のすべてのオブジェクトは辞書で、これは「のtoString」と他のすべての方法は、すべてのオブジェクト

var myObj = {}; 
console.log(myObj["toString"]); 

の鍵となります。しかしhasOwnPropertyを、この場合はわかりますように、この関数は、Objectクラスから継承されることを意味しキーはディクショナリによって所有されているか、または継承されています。

"toString" in myObj; // true 
myObj.hasOwnProperty("toString") // false 
1

@blockheadがここにあります。たとえば、Prototype.jsフレームワークは、余分なヘルパーメソッドでネイティブ配列を拡張するために使用されていました(現在のバージョンのフレームワークではわかりません)。 "for(key in dict)"を直接使用すると、divのすべての要素とヘルパーメソッドへの参照が返されます。予期せぬものです

26

メソッドは、プロパティがオブジェクトのインスタンス上に直接存在するか、プロトタイプチェーンから継承されているかどうかを知ることができます。

は、以下の

function ObjWithProto() { 
    this.foo = 'foo_val'; 
} 

ObjWithProto.prototype = {bar: 'bar_val'}; 

var dict = new ObjWithProto(); 
dict.foobar = 'foobar_val'; 

すなわちを考えてみましょうあなたはまた、それのプロトタイプチェーンからプロパティbarを継承するプロパティfoofoobarオブジェクトdictを持っています。今

function forEach(dict) { 
    var key; 
    for (key in dict) { 
     if (dict.hasOwnProperty(key)) console.log('has', key, dict[key]); 
     else console.log('not', key, dict[key]); 
    } 
} 
forEach(dict); 

あなたはこれは、それが継承しているこれらのオブジェクトが自身を持っているあなたの別々のプロパティをすることができますし、

has foo foo_val 
has foobar foobar_val 
not bar bar_val 

表示されます(修正版)あなたのコードを介して実行され

また、dict.bar = 'new_bar_val';を実行すると、最後の結果はに変更されますでは、継承されたものと同じ名前のプロパティ間でも区別できます。