Benefit of using Object.hasOwnProperty vs. testing if a property is undefined
Asked Answered
S

3

28

Since hasOwnProperty has some caveats and quirks (window / extensive use in Internet Explorer 8 issues, etc.):

Is there any reason to even use it? If simply testing if a property is undefined, is it better justified and more simplistic?

For example:

var obj = { a : 'here' };

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

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

I'd prefer to be using the most cross-browser friendly, and up to date methodology.

I've also seen this prototype overwritten for hasOwnProperty, which works, but I'm not sold on its usefulness...

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]);
    };
}
Sweater answered 17/6, 2013 at 14:46 Comment(4)
Anything other than using hasOwnProperty is guaranteed to produce false positives or negativesBiafra
if i know i'm looking for an array or object or function, i prefer it even simpler: if (obj.a) . Of course, if obj.a can be zero, "", or false, then comparing it to be !== undefined is required. also, this object has an "a" according to ("a" in obj), but not if(obj.a): {a:undefined}Erlking
Additional info: You might find this jsPerf test interesting: jsperf.com/hasownproperty-vs-in/2. Bottom line: .hasOwnProperty is a lot slower than any other way of testing property existence (that was surprising for me TBH).Islamite
@FelixKling interesting jsperf. However .hasOwnProperty and in have very different meaning. Quoting Mozilla documentation: "obj.hasOwnProperty(prop)" used to determine whether an object has the specified property as a direct property of that object; unlike the in operator, this method does not check down the object's prototype chain.Gertiegertrud
B
4

As further information to the answer given by Pavel Gruba, and the polyfil that you supplied:

To the best of my knowledge, there is no good way to polyfil hasOwnProperty for browsers that do not support it natively. I have seen quite a few different ones in the wild and they all produce false positives or negatives. If I have absolutely no alternative then this is what I created for my use, but it also suffers false positives and negatives. According to MSDN.

Supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards, Internet Explorer 9 standards, Internet Explorer 10 standards. Also supported in Windows Store apps.

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")
}

On JSFiddle.

Biafra answered 17/6, 2013 at 15:26 Comment(0)
A
23

hasOwnProperty does not check for undefined values. It only checks if a property is assigned to the object even if is undefined:

var obj = { a : undefined };
obj.hasOwnProperty("a") // true
obj.a === undefined     // true
obj.hasOwnProperty("b") // false
obj.b === undefined     // true
Angelicangelica answered 26/3, 2015 at 6:52 Comment(0)
M
22

The hasOwnProperty method checks that a property is assigned to the object directly.

So, if property 'a' is in the prototype, hasOwnProperty will filter that.

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

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

So, hasOwnProperty is safer in many cases.

Metz answered 17/6, 2013 at 15:9 Comment(1)
Very true... Just realized this after posting the question! I'm having a hard time finding browser support for hasOwnProperty, is it at least IE7+ compatible?Sweater
B
4

As further information to the answer given by Pavel Gruba, and the polyfil that you supplied:

To the best of my knowledge, there is no good way to polyfil hasOwnProperty for browsers that do not support it natively. I have seen quite a few different ones in the wild and they all produce false positives or negatives. If I have absolutely no alternative then this is what I created for my use, but it also suffers false positives and negatives. According to MSDN.

Supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards, Internet Explorer 9 standards, Internet Explorer 10 standards. Also supported in Windows Store apps.

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")
}

On JSFiddle.

Biafra answered 17/6, 2013 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.