20

foo特定のオブジェクト(例)に特定のプロパティ(例bar)が定義されているかどうかを判断する方法は4つあるように思われます。

  1. if (foo.hasOwnProperty(bar)) {
  2. if ('bar' in foo) {
  3. if (typeof foo.bar !== 'undefined') {
  4. if (foo.bar === undefined) {

barオブジェクトに""という名前のプロパティがあるかどうかを判断するには、fooこれら3つのステートメントすべてが同等ですか?これらの3つのステートメントのいずれかを異なるものにする、私が知らない微妙なセマンティクスはありますか?

4

6 に答える 6

17

いいえ、まったく違います。例:

foo = {bar: undefined};
Object.prototype.baz = undefined;
Object.prototype.bing = "hello";

それで:

(typeof foo.bar != "undefined")  === false
('bar' in foo)                   === true
(foo.hasOwnProperty('bar'))      === true


(typeof foo.baz != "undefined")  === false
('baz' in foo)                   === true
(foo.hasOwnProperty('baz'))      === false


(typeof foo.bing != "undefined") === true
('bing' in foo)                  === true
(foo.hasOwnProperty('bing'))     === false

論理的に:

  • foo.hasOwnProperty('bar')示す'bar' in foo
  • typeof foo.bar != "undefined"示す'bar' in foo
  • しかし、これらはあなたが引き出すことができる唯一の推論です。上記の反例が示すように、他の含意は普遍的に真ではありません。
于 2011-12-16T20:51:07.467 に答える
10

これらはすべて異なります。

  1. foo.hasOwnProperty('bar')プロパティを持っているかどうかfooを示し、プロトタイプ チェーンに沿ってルックアップを実行しません。

  2. 'bar' in foobarプロトタイプ チェーンをチェックし、チェーンに沿った任意のオブジェクトにプロパティが見つかった場合に true を返します。

  3. typeof foo.bar != 'undefined'fooは、またはそのプロトタイプ チェーンに沿ったいずれかのオブジェクトにプロパティがbarあり、その値が ではない場合に true を返しますundefined

これらの違いを示す例を次に示します。

var foo1 = { 'bar1': 10, 'bar2': undefined };
function ctor() {}
ctor.prototype = foo1;
var foo2 = new ctor();
foo2.bar3 = 20;

console.log(foo2.hasOwnProperty('bar1')); // false
console.log(foo2.hasOwnProperty('bar2')); // false
console.log(foo2.hasOwnProperty('bar3')); // true
console.log(foo2.hasOwnProperty('bar4')); // false

console.log('bar1' in foo2); // true
console.log('bar2' in foo2); // true
console.log('bar3' in foo2); // true
console.log('bar4' in foo2); // false

console.log(typeof foo2.bar1 != 'undefined'); // true
console.log(typeof foo2.bar2 != 'undefined'); // false
console.log(typeof foo2.bar3 != 'undefined'); // true
console.log(typeof foo2.bar4 != 'undefined'); // false
于 2011-12-16T20:52:11.427 に答える
2

1 つの違いは、メソッド 1 はプロパティ bar の foo オブジェクトのみをチェックするのに対し、最後の 2 つのメソッドは継承されたプロパティのプロトタイプもチェックすることです。

于 2011-12-16T20:50:33.730 に答える
2
'bar' in foo 

プロトタイプ チェーンの任意の場所を検索します。foo.bar!==が のプロトタイプ チェーンのどこかにundefinedある場合も true を返すかどうかをテストします が、barfoo で定義されていて未定義に設定されている場合、これは false を返すことに注意してください。barfoo

hasOwnPropertybarはより選択的です。の直接プロパティとして定義されているtrue のみを返しますfoo

MDN ごと

Object から派生したすべてのオブジェクトは、hasOwnProperty メソッドを継承します。このメソッドを使用して、オブジェクトが指定されたプロパティをそのオブジェクトの直接プロパティとして持っているかどうかを判断できます。in 演算子とは異なり、このメソッドはオブジェクトのプロトタイプ チェーンをチェックしません。

于 2011-12-16T20:51:04.010 に答える
2

実際、さまざまなメソッド/キーワードには微妙な違いがいくつかあります。

  1. foo.hasOwnProperty('bar')プロパティ「bar」が foo オブジェクト自体で定義されている場合にのみ true を返します。ただし、「toString」などの他のプロパティは、プロトタイプ チェーンで定義されているため、false を返します。

  2. in指定されたプロパティが指定されたオブジェクトにある場合、キーワード演算子は true を返します。'bar' in fooとの両方'toString' in fooが true を返します。

  3. プロパティの状態をチェックしているため、foo に bar が定義されていない場合、および bar が定義されているが値が に設定されている場合、結果は true になりますundefined

于 2011-12-16T20:56:11.460 に答える
0

他の人が言ったことに追加するには、プロパティが存在し、偽ではない値 ( undefinednullfalse0""NaNなどではない) を持っているかどうかだけを知りたい場合は、次のようにします。

if (foo.bar) {
     // code here
}

特定の状況で誤った値に興味がない限り、このショートカットは変数があなたにとって有用なものに設定されているかどうかを教えてくれます。

プロパティが何らかの方法でオブジェクトに存在するかどうかを知りたい場合は、これが最も便利で、簡潔で読みやすいと思います。

if ('bar' in foo) {
    // code here
}

関数の引数に同様のものを使用することもできます (偽の値が気にならない限り):

function foo(bar) {
    if (bar) {
        // bar was passed and has some non-falsey value
    }
}
于 2011-12-16T21:09:00.867 に答える