8

jQuery のソース コードを調べていたところ、JavaScript オブジェクトが空かどうかを検出するために、この小さなコード スニペットが使用されていることがわかりました。

function isMyObjEmpty( obj ) {
    var name;
    for (name in obj ) {
        return false;
    }
    return true;
}

なぜこれが機能するのか、誰かが私に説明できますか? なぜこれがtrueを返すのか理解できません。

4

6 に答える 6

17

機能する理由:

これは、for... inループを使用してオブジェクトのプロパティを反復処理します。

オブジェクトにプロパティがある場合、ループに入って戻りますfalse

オブジェクトにプロパティがない場合、ループに入らず、 を返しtrueます。

できない理由:

動作しない場合がありますのでご注意ください。for.. inループはプロパティのみを通過enumerableするため、技術的にはオブジェクトが空でなくても false が返されます。プロパティを列挙できないように定義して、このメソッドをだますことができます。これが問題のケースです。

正しいことは、このメソッドは、オブジェクトに列挙可能なプロパティがあるかどうかをチェックするということです。

ドキュメントの内容:

メソッドのドキュメントはこちらにあります

説明: オブジェクトが空 (列挙可能なプロパティを含まない) かどうかを確認します。

個人的には、彼らがそのメソッドを呼び出すのは奇妙だと思いますisEmptyObject。の方がふさわしい名前だと思いますhasNoEnumerableProperties

オブジェクトが空かどうかを本当に確認したい場合はどうすればよいでしょうか?

JS の新しい実装では、Object.getOwnPropertyNames. getOwnPropertyNames列挙可能かどうかに関係なく、すべてのプロパティを取得します。

isMyObjEmptyで実装できますObject.getOwnPropertyNames(myObject).length===0。これにより、列挙可能かどうかに関係なく、オブジェクトにプロパティがないことが確認されます。

ただし、これはプロトタイプのプロパティをチェックしません。これは望ましい動作かもしれませんし、望ましくないかもしれません。それについてのシャドウモンキーとの議論を確認してください。Object.getPrototypeOfこれは、再帰的に呼び出しを行い、プロトタイプチェーン全体でプロパティをチェックすることで簡単に解決できます。

于 2013-03-28T20:06:33.970 に答える
1

見つかっnameた場合objは、obj に何かがあり、空ではありません。それができない場合は、obj が空であると言って true を返します。

于 2013-03-28T20:06:28.063 に答える
0

これを試して。これは、オブジェクト自体のプロパティによるものだと思います。プロトタイプ プロパティにアクセスしないようにするには、hasOwnProperty が必要です。

 function isMyObjEmpty( obj ) {
        var name;
        for (name in obj ) {
          if(obj.hasOwnProperty(name)) {
            return false;
          }
        }
        return true;
    }

ドキュメントを読んで、そこに書かれている意味を確認してください。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in

于 2013-03-28T20:08:19.980 に答える
0

そうではないかもしれませんが、混乱はobjのキー「name」に起因すると想定しています。オブジェクト内の name と呼ばれるキーを実際に探すのではなく、オブジェクト内のすべてのキーが name と呼ばれる変数に割り当てられています。したがって、オブジェクト内に何かが見つかった場合は false を返し、実際に空のオブジェクトではないことを確認します。ただし、オブジェクトに何も見つからない場合は、オブジェクトが空であることを意味する true を返します。

于 2013-03-28T20:09:44.853 に答える
0

重要なのは、for..in ループがオブジェクトのすべてのプロパティを反復することですが、それ以外は何も反復しません。オブジェクトに何もない場合、そのループは実行されないため、"return false" 行は実行されません。次に、プログラムは次の行に進み、true を返すように指示します。

(これは興味深い質問そのものにつながります。その for..in ループは hasOwnProperty() チェックでラップする必要がありますか? それとも、関数は実際に所有されていないプロパティをキャッチし、それに基づいてオブジェクトを空でないものとしてカウントするつもりですか?)

于 2013-03-28T21:00:43.427 に答える
-1

もちろん、オブジェクトが空の場合、いつtrueを返しますか。

isMyObjEmpty({});

それはどのように機能しますか?for...inを使用して


のために...で

概要

オブジェクトの列挙可能なプロパティを任意の順序で反復処理します。個別のプロパティごとに、ステートメントを実行できます。

したがって、プロパティがない場合、 for in ループには入りません。hasOwnProperty()誤検知につながる可能性があるため、ループは実際にチェックする必要があります。

于 2013-03-28T20:06:35.920 に答える