Reputation: 185
I encountered this difference between undefined
and "undefined"
and I am trying to understand it.
I was checking whether properties in objects are defined or not.
In first example I checked whether property is not undefined. All the test below evaluates to true. It doesn't matter whether I use "undefined"
or undefined
.
var test = {
x: 1,
y: 2
};
if (test.x != "undefined") console.log('test.x != "undefined"'); //TRUE
if (test.x !== "undefined") console.log('test.x !== "undefined"'); //TRUE
if (test.x != undefined) console.log('test.x != undefined'); //TRUE
if (test.x !== undefined) console.log('test.x !== undefined'); //TRUE
Then I tried it with property which is not defined.It only evaluates to true if i use undefined
(not string literal) or with typeof
.
var test = {
x: 1,
y: 2
};
if (test.z === undefined) console.log("test.z === undefined"); //TRUE
if (test.z == undefined) console.log("test.z == undefined"); //TRUE
if (test.z === "undefined") console.log("test.z === 'undefined'"); //FALSE
if (test.z == "undefined") console.log("test.z == 'undefined'"); //FALSE
if (typeof test.z === "undefined") console.log("typeof test.z === 'undefined'"); //TRUE
So my question is: why the difference (I guess I don't understand something ...). Is it bad practice that I used comparison to "undefined"/undefined rather than .hasOwnProperty()
?
Upvotes: 0
Views: 200
Reputation: 1074445
undefined
and "undefined"
are different values. The former is undefined
, the latter is a string.
What you've probably seen isn't x === "undefined"
and x === undefined
, but rather typeof x === "undefined"
and x === undefined
. Note the typeof
. One of the reasons you see the former (with typeof
) is historic and no longer relevant, but not all of the reasons are.
Assuming a declared identifier x
and that undefined
has not been shadowed, these two statements are effectively the same other than the first one has to do a teensy bit more work:
typeof x === "undefined"
x === undefined
But if x
isn't declared, the former will evaluate true, and the latter will fail with a ReferenceError. (In the general case, you probably want the ReferenceError as it alerts you to the undeclared idenfier, but there are use cases for the former.)
But undefined
is, unfortunately, not a keyword (like null
); it's a global constant. That means that undefined
can be shadowed:
function foo(undefined) {
var x; // x defaults to the value undefined
console.log(typeof x === "undefined"); // true
console.log(x === undefined); // false?!?!
}
foo(42);
In practice, if you find someone shadowing undefined
and giving it a value other than undefined
, take them out back and beat them about the head and shoulders with a wet noodle until they see sense. But...
Historically, there was many years ago a problem with the undefined
value in one window not being ===
to the undefined
value. And so if you had code that might be dealing with values from across windows, comparing with === undefined
wasn't a reliable way to check for undefined
. A couple of years back I checked all even vaguely-recent browsers and that wasn't an issue (I suspect it hasn't been for much longer than that).
Upvotes: 1
Reputation: 278
When you are checking for "undefined"
(in quotes) then you are checking for string with value "undefined"
.
Whereas when you are checking for undefined
then it is checked if the property or the variable is defined or not. Therefore you can use this to check if the property is defined.
Upvotes: 1