web-dev-qa-db-ja.com

Object.hasOwnPropertyを使用することと、プロパティが未定義かどうかをテストすることの利点

hasOwnPropertyには、いくつかの注意点と癖があります(ウィンドウ/ ie8の問題での広範な使用など)。

それを使用する理由があるかどうか、そしてプロパティが未定義であるかどうかを単にテストする方が正当化され、より単純化されているかどうか疑問に思いました。

例えば:

var obj = { a : 'here' };

if (obj.hasOwnProperty('a')) { /* do something */ }

if (obj.a !== undefined) { /* do something */ }
// or maybe (typeof (obj.a) !== 'undefined')

誰かがこれについて良い洞察を持っているかどうか疑問に思っているので、私は最もクロスブラウザに優しい、そして最新の方法論を使用したいと思います。

このプロトタイプがhasOwnPropertyで上書きされるのも見ましたが、これは機能しますが、その有用性については売られていません...

if (!Object.prototype.hasOwnProperty) {
    Object.prototype.hasOwnProperty = function(prop) {
        var proto = this.__proto__ || this.constructor.prototype;
        return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);
    };
}

@Pavel Grubaによって与えられた回答、およびあなたが提供したポリフィルへのさらなる情報として。私の知る限り、ネイティブでサポートされていないブラウザでhasOwnPropertyをポリフィルする良い方法はありません。私は野生でかなりの数の異なるものを見てきました、そしてそれらはすべて偽陽性または偽陰性を生み出します。代替手段がまったくない場合、これは私が使用するために作成したものであり、誤検知と誤検知も発生します。 [〜#〜] msdn [〜#〜] によると。

次のドキュメントモードでサポートされています:Quirks、Internet Explorer 6標準、Internet Explorer 7標準、Internet Explorer 8標準、Internet Explorer 9標準、Internet Explorer10標準。 Windowsストアアプリでもサポートされています。

Javascript

function is(x, y) {
    if (x === y) {
        if (x === 0) {
            return 1 / x === 1 / y;
        }

        return true;
    }

    var x1 = x,
        y1 = y;

    return x !== x1 && y !== y1;
}

function hasOwnProperty(object, property) {
    var prototype;

    return property in object && (!(property in (prototype = object.__proto__ || object.constructor.prototype)) || !is(object[property], prototype[property]));
}

function NewClass() {}
NewClass.prototype = {
    a: 'there'
};

var obj = new NewClass();

if (obj.hasOwnProperty("a")) {
    console.log("has property")
}

if (hasOwnProperty(obj, "a")) {
    console.log("has property")
}

オン jsfiddle

3
Xotic750

HasOwnPropertyメソッドは、プロパティがオブジェクトに直接割り当てられていることを確認します。したがって、プロパティ 'a'がプロトタイプにある場合、hasOwnPropertyはそれをフィルタリングします。

function NewClass() {}
NewClass.prototype = { a: 'there' };
var obj = new NewClass();

if (obj.hasOwnProperty('a')) { /* code does not work */ }
if (obj.a !== undefined) { /* code works */ }

したがって、多くの場合、hasOwnPropertyの方が安全です。

14
Pavel Gruba

hasOwnPropertyは未定義の値をチェックせず、プロパティがオブジェクトに割り当てられているかどうかをチェックします。

var obj = { a : undefined }; 
obj.hasOwnProperty("a") //true 
obj.a === undefined     //true
obj.hasOwnProperty("b") //false
obj.b === undefined     //true   
10
dpineda