Skip to content Skip to sidebar Skip to footer

Typeof Foo['bar'] !== 'undefined' Vs. 'bar' In Foo

What's the difference between the return values of these two expressions... Expression 1: typeof foo['bar'] !== 'undefined' Expression 2: 'bar' in foo ... assuming that these condi

Solution 1:

The first tests the value of bar in foo.

The second tests for the existence of the bar property in foo.

var foo = {bar:undefined};

typeof foo['bar'] !== 'undefined'; // false'bar'in foo;  // true

EDIT:

To add some clarification from the comments below, the issue OP is having is that accessing the domConfig property of window.document throws an Error.

This is an issue not related to the typeof operator, but rather to a specific issue with Firefox.

The issue has been documented here as a bug (back in 2003).

A few notable comments from that report:

Zbigniew Braniecki [:gandalf] 2003-11-19 09:09:31 PST

then why it can be iterated with for-in ?

Boris Zbarsky (:bz) 2003-11-19 09:24:05 PST

Because it is defined as a property on the nsIDOM3Document interface. It's just one that throws if you try to access its getter. ...

Zbigniew Braniecki [:gandalf] 2003-11-19 09:33:53 PST

... So what kind of bug is it?

The goal is to remove not implemented method/property from interface or to implement it?!?

Boris Zbarsky (:bz) 2003-11-19 09:53:23 PST

The goal is to eventually implement this.

Solution 2:

My reading of the spec suggests that they should be the same. The "in" operator semantics are defined in terms of making a call to the internal (conceptual) [[HasProperty]] method, which itself is defined in terms of [[GetProperty]]. When [[HasProperty]] returns "undefined", then the "in" operator results in boolean false; otherwise it's true. Based on the definition of what [[GetProperty]] is supposed to do, that means that an "undefined" result of a property access would have the same meaning.

Solution 3:

Given the conditions you outline, there is no difference. Both should produce the same boolean result and should behave the same around prototype lookup.

Object.prototype.hasOwnProperty.call(null, foo, 'bar')

is another common idiom that does the same as those two but does not incude properties available only on the prototype.

Solution 4:

var foo = {};
foo.bar = undefined;

console.log("bar"in foo); // trueconsole.log(typeof foo["bar"] !== "undefined"); // falsevarCon = function() {};
Con.prototype.bar = undefined;
var foo = newCon;

console.log("bar"in foo); // trueconsole.log(typeof foo["bar"] !== "undefined"); // false

The in check is simply the same as using a for in loop and returning true if the key is in the for in loop.

[Edit] Didn't see your "don't explicity set it to undefined" condition.

var foo = {}
Object.defineProperty(foo, "bar", { 
    "value": 42,
    "enumerable": false

});

console.log("bar"in foo); // true (in chrome & FF4)console.log(typeof foo["bar"] !== 'undefined'); // true

I actaully expected the in test to fail if you set it as non-enumerable. Seems like they are the same.

var foo = {}
Object.defineProperty(foo, "bar", { 
    "value": 42,
    "writable": false

});

console.log("bar"in foo); // true (in chrome & FF4)console.log(typeof foo["bar"] !== 'undefined'); // true

Both test still work if the property is "readonly"

var foz = {}
Object.defineProperty(foz, "bar", { 
    "value": 42
});
var foo = Object.freeze(foz);

console.log("bar"in foo); // true (in chrome & FF4)console.log(typeof foo["bar"] !== 'undefined'); // true

Freezing the object also doesn't break the tests.

Solution 5:

Given those two conditions, the expressions should give you identical results, except if

  • foo has an EcmaScript 5 getter defined for the bar property. Since the first expression actually reads the property value, that getter will be invoked. The second expression merely checks for the existence of the property so there is no need to incoke any such getter.
  • you are targeting Internet Explorer 4.0 - the in operator wasn't added until JavaScript 1.4 ;)

Here's some sample code to illustrate the difference in supporting browsers (Chrome, IE9, FF4):

var foo = {};
Object.defineProperty(foo, "bar", { 
    "get": function () {document.write("Getter invoked!<br/>"); return foo;}
});

document.write('"bar" in foo -->' + 
               ("bar"in foo));
document.write('<br/>');
document.write('typeof foo["bar"] !== "undefined" -->' +
               (typeof foo["bar"] !== "undefined"));
document.write('<br/>');

Post a Comment for "Typeof Foo['bar'] !== 'undefined' Vs. 'bar' In Foo"