20

このスニペットを見て、

var a = {

}

if(typeof a.c === 'undefined'){
 console.log('inside if');
}
if(a.c === undefined){
 console.log('inside if');
}

どちらもifになりますtrue一部のブラウザに固有の両方のステートメントに違いはありますか?

また、私の最後のプロジェクトでは、データtypeof a.c == 'undefined'の値をチェックするためにすでに何度も使用していjsonます。

さて、これは良い方法ではないことを知っています。値もある可能性があるundefinedため、私のロジックは失敗します。

使うべきだっhasOwnPropertyた。

しかし、値はないと確信しています。代わりundefinedに使用できますか、またはすべてを変更する必要がありますtypeof a.c == 'undefined'hasOwnPropertytypeofhasOwnProperty

4

3 に答える 3

31

更新:この質問をチェックしたいかもしれません:variable === undefined vs. typeof variable === "undefined")。

非常に古いブラウザ (Netscape 2、IIRC、およびおそらく IE 4 以下) ではundefined、エラーが発生したため、値を と比較できませんでした。typeof value === 'undefined'ただし、(半)最新のブラウザーでは、代わりにチェックする理由はありませんvalue === undefined(誰かが変数を再定義した可能性があるというパラノイアを除いてundefined)。

hasOwnProperty別の目的を果たします。オブジェクトがそのプロトタイプではなく、指定された名前のプロパティを持っているかどうかを確認します。つまり、継承されたプロパティに関係なく。オブジェクトに特定のプロパティが含まれているかどうか、継承されているかどうかを確認したい場合は、if ('c' in a) {...を使用する必要があります。

しかし、基本的に、これらはおそらくすべて機能します。

if (a.c === undefined) console.log('No c in a!');
if (typeof a.c === 'undefined') console.log('No c in a!');
if (!('c' in a)) console.log('No c in a!');
if (!a.hasOwnProperty('c')) console.log('No c in a!');

主な違いは次のとおりです。

  • a.c === undefinedundefined = 'defined'誰かがやった、またはそのようなトリックを行った場合、予期しない結果が生成されます。
  • !('c' in a)あまり読みにくい(IMHO)
  • !a.hasOwnProperty('c')falseオブジェクトaにプロパティが含まれていないが、cそのプロトタイプが含まれている場合に返されます。

個人的には前者の方が読みやすいので好きです。偏執的で、再定義された のリスクを回避したい場合は、undefined次のように自己実行型の無名関数でコードをラップします。

(function (undefined) {
  // in here, 'undefined' is guaranteed to be undefined. :-)

  var a = {

  };

})();
于 2012-06-05T10:14:03.103 に答える
3

JSON 文字列を解析した結果である標準オブジェクトをチェックしても、.hasOwnProperty明らかな利点がない場合。もちろん、あなたまたはあなたが使用しているいくつかのライブラリがObject.prototype.

一般に、undefinedそのようなものは再定義できますが、私はこれに遭遇したことはありません。また、今後もそうなるとは思いません。ただし、の戻り値を台無しにすることは(私の知る限り)不可能ですtypeof。そういう意味では後者が無難です。undefined古いブラウザーの中には、このキーワードでもうまく機能しないものがあると思います。

typeof再開する場合: すべてのチェックを取り替える必要はありません。個人的な注意点として、 を使用する習慣を身につけるのは良い習慣だと思い.hasOwnPropertyます。したがって、プロパティが存在する可能性があるが未定義の場合.hasOwnPorpertyは、最も安全な方法であることをお勧めします。


あなたのコメントへの回答: はい、typeof~95% の確率であなたのニーズに適合します。.hasOwnProperty99% の時間で動作します。ただし、名前が示すように、継承チェーンの上位にあるプロパティはチェックされません。次の例を検討してください。

Child.prototype = new Parent();
Child.prototype.constructor=Child;//otherwise instance.constructor points to parent

function Parent()
{
    this.foo = 'bar';
}

function Child()
{
    this.bar = 'baz';
}

var kiddo = new Child();
if (kiddo.hasOwnProperty('foo'))
{
    console.log('This code won\'t be executed');
}
if (typeof kiddo.foo !== 'undefined')
{
    console.log('This will, foo is a property of Parent');
}

したがって、単一のオブジェクトにプロパティがhasOwnPropertyあるかどうかを確認したい場合は、それが必要です。特に、そのプロパティの値を変更する場合 (プロトタイプ プロパティの場合は、すべてのインスタンスを変更できます)。継承チェーンのどこにあるかに関係なく
、プロパティに値があるかどうか ( 以外) を知りたい場合は、 が必要です。プロパティが継承チェーンのどこにあるかを判断するための再帰関数がどこかにあります。こちらも見つけ次第掲載させていただきます。undefinedtypeof

アップデート:

お約束どおり、継承チェーン内のプロパティを検索する関数。しばらく前に使用した実際の機能ではないので、ワーキング ドラフトをまとめました。完璧ではありませんが、途中で役立つ可能性があります。

function locateProperty(obj,prop,recursion)
{
    recursion = recursion || false;
    var current = obj.constructor.toString().match(/function\s+(.+?)\s*\(/m)[1];
    if (!(obj.hasOwnProperty(prop)))
    {
        if (current === 'Function' || recursion === current)
        {
            return false;
        }
        return locateProperty(new window[current](),prop,current);
    }
    return current;
}
//using the object kiddo
locateProperty(kiddo,'foo');//returns 'Parent'
locateProperty(kiddo,'bar');//returns 'Parent', too

この最後の不具合を回避するには、最後のreturn current;ステートメントをreturn obj;. または、さらに良いのは、上記のスニペットに次の行を追加することです。

Child.prototype.constructor=Child;

最初の編集で忘れてた…

于 2012-06-05T10:22:07.523 に答える
0
  • p の列挙可能なプロパティを o にコピーし、o を返します。

  • o と p に同じ名前のプロパティがある場合、o のプロパティはそのままになります。

  • この関数は、getter と setter を処理したり、属性をコピーしたりしません。

    function merge(o, p) 
    {
        for(prop in p) 
        {   
            // For all props in p.
            if (o.hasOwnProperty[prop]) continue;  // Except those already in o.
            o[prop] = p[prop];                     // Add the property to o.
        }
    
        return o;
    }
    

o.hasOwnProperty[prop]とはどう違いo.hasOwnProperty(prop)ますか?

于 2012-06-16T16:32:05.063 に答える