197

次の2つのステートメントは同じ出力を生成しますか?ある方法を他の方法よりも好む理由はありますか?

 if (key in object)

 if (object.hasOwnProperty(key))
4

8 に答える 8

200

注意してください-それらは同じ結果を生成しません。

inプロトタイプチェーンのどこかで見つかったtrue場合にも返されますが、 (名前がすでに示しているように)、そのオブジェクトで直接利用可能な場合(プロパティを「所有」している場合)にのみ返されます。keyObject.hasOwnPropertytruekey

于 2012-11-29T19:16:03.697 に答える
75

別の例で説明しようと思います。2 つのプロパティを持つ次のオブジェクトがあるとします。

function TestObj(){
    this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';

TestObj のインスタンスを作成しましょう。

var o = new TestObj();

オブジェクト インスタンスを調べてみましょう。

console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true

console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true

結論:

  • プロパティがオブジェクトから直接またはプロトタイプからアクセスできる場合、in 演算子は常に true を返します。

  • hasOwnProperty() は、プロパティーがインスタンスに存在し、そのプロトタイプには存在しない場合にのみ true を返します

プロトタイプに何らかのプロパティが存在することを論理的に確認したい場合は、次のように言います。

console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype

ついに:

それで、これら2つの条件という声明について...

if (key in object)
if (object.hasOwnProperty(key))

...同じ結果が得られます。答えは明らかで、状況によって異なります。

于 2014-11-28T14:10:57.387 に答える
33

in継承されたプロパティもチェックしますが、はそうではありませんhasOwnProperty

于 2012-11-29T19:15:53.223 に答える
32

要約hasOwnProperty()すると、プロトタイプinは見ますが、プロトタイプは見ません。

O'Reilly High Performance Javascriptから取得:

hasOwnProperty() メソッドを使用してメンバーの名前を渡すことにより、オブジェクトが特定の名前のインスタンス メンバーを持っているかどうかを判断できます。オブジェクトが特定の名前のプロパティにアクセスできるかどうかを判断するには、in 演算子を使用できます。例えば:

var book = {
    title: "High Performance JavaScript",
    publisher: "Yahoo! Press" 
};

alert(book.hasOwnProperty("title"));  //true
alert(book.hasOwnProperty("toString"));  //false
alert("title" in book); //true 
alert("toString" in book); //true

このコードでは、「title」が渡されると hasOwnProperty() は true を返します。title はオブジェクト インスタンスであるためです。インスタンスに存在しないため、「toString」が渡されるとメソッドは false を返します。各プロパティ名を in 演算子で使用すると、インスタンスとプロトタイプが検索されるため、結果は両方とも true になります。

于 2015-04-23T15:06:17.790 に答える
2

もう 1 つの形式 (in で呼び出される) は、オブジェクトのプロパティ名 (またはキー) を列挙します。各反復で、オブジェクトの別のプロパティ名文字列が変数に割り当てられます。通常、object.hasOwnProperty(variable) をテストして、プロパティ名が本当にオブジェクトのメンバーであるか、または代わりにプロトタイプ チェーンで見つかったかを判断する必要があります。

 for (myvar in obj) {
     if (obj.hasOwnProperty(myvar)) { ... } }

(Crockford のJavascript: The Good Partsから)

于 2012-11-29T19:18:09.350 に答える
-5

最初のバージョンは短くなっています(特に変数の名前が変更された縮小コードでは)

a in b

vs

b.hasOwnProperty(a)

とにかく、@ AndreMeinholdが言ったように、それらは常に同じ結果を生成するとは限りません。

于 2012-11-29T19:15:58.473 に答える