76

重複の可能性:
オブジェクトが JavaScript で特定のプロパティを持っているかどうかを確認するにはどうすればよいですか?

Twitter の JavaScript ファイルで次のスニペットを見つけました。プロパティがあるhasOwnPropertyことを確認するために関数を呼び出す必要があるのはなぜですか? forループは、'dict' の各 'key' に対して実行されます。これは、'dict' に 'key' があることを意味します。ポイントがありませんか?dictkey

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

4 に答える 4

78

そうしないと、知らないもの (ネイティブ オブジェクト プロトタイプをいじっている誰かによって追加された可能性がある) を含め、プロトタイプ チェーンのすべてのプロパティをループしてしまうからです。

このようにして、そのオブジェクト インスタンス自体にあるキーのみが保証されます。

于 2012-10-04T20:57:34.273 に答える
36

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

次のことを考慮してください

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

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

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

つまり、プロパティを持つオブジェクト があり、そのプロトタイプ チェーンからプロパティも継承します。dictfoofoobarbar

次に、コード (の修正版) を実行します。

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';と、最後の結果が に変わりhas bar new_bar_val、同じ名前のプロパティであっても継承されたものと区別できるようになります。

于 2012-10-04T21:09:08.360 に答える
5

JavaScript のすべてのオブジェクトは辞書です。これは、「toString」と他のすべてのメソッドがすべてのオブジェクトのキーであることを意味します。

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

ただし、この関数は Object クラスから継承されているため、 hasOwnProperty は、このキーが辞書によって所有されているか、継承されているかを示します。

"toString" in myObj; // true
myObj.hasOwnProperty("toString") // false
于 2012-10-04T20:59:19.413 に答える
1

ブロックヘッドはここにあります。たとえば、Prototype.js フレームワークは、追加のヘルパー メソッドを使用してネイティブ配列を拡張するために使用されていました (現在のバージョンのフレームワークの状況はわかりません)。

したがって、「for (key in dict)」を直接使用すると、div のすべての要素とヘルパー メソッドへの参照が返されます。これはちょっと予想外です:)

于 2012-10-04T21:02:19.413 に答える