Typeof Foo['bar'] !== 'undefined' Vs. 'bar' In Foo
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 thebar
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"