I saw this question in a test, where the variable myObj was not declared, and requsted to choose the correct answer based on the following if statements.
function myFunction() {
if(typeof myObj !== "undefined" && myObj !== null) {
a = 1
}
}
result: "undefined"
Created the functions to run these statements and test output.
function myFunction() {
if(myObj !== null && typeof myObj !== "undefined") {
a = 1
}
}
result: Uncaught ReferenceError: myObj is not defined
my questions is if an variable is not defined, isn't that the same as "undefined", if I want to test for a "undefined" value, I can just use "null" to check if its undefined by (e.g myObj === null), so why is the fist function returns undefined and the second returns myObj is not defined?
There are a couple of things going on:
Value checks are different from type checks.
If you try to read the value of an identifier that doesn't exist, you get an error. So myObj === null
causes an error if myObj
doesn't exist (the identifier has never been declared or otherwise created).
But using typeof
on an identifier that doesn't exist results in "undefined"
, without an error. So typeof myObj
is "undefined"
when myObj
doesn't exist. You can see this in the specification where it does:
2(a) If IsUnresolvableReference(val) is true, return "undefined".
The &&
operator short-circuits.
&&
evaluates its first operand and, if that value is falsy,¹ takes the falsy value as its result, doing nothing with the second operand. If the first operand's value is truthy, though, &&
evaluates the second operand and takes that value as its result.
Because of those two things, if(typeof myObj !== "undefined" && myObj !== null) {
works without error because it does typeof myObj !== "undefined"
first and, since that value is false
when myObj
doesn't exist, the result of the &&
operation is true
and the second operand is never evaluated. But if(myObj !== null && typeof myObj !== "undefined") {
does myObj !== null
first, trying to use the value of an identifier that doesn't exist, which causes the error.
my questions is if an variable is not defined, isn't that the same as "undefined"
Not in the general case, no. typeof
is special. Just about anything else you do with an identifier that doesn't exist will raise an error. (Okay, there's one other thing: in loose mode, if you assign to an identifier that doesn't exist, it creates a global. This is what I call The Horror of Implicit Globals and is one of the many reasons to use strict mode, where it's the error it always should have been.)
¹ "truthy" and "falsy" are terms we use in JavaScript to refer to vlaues that coerce to true
and values that coerce to false
when used as conditions. There is a fixed set of falsy values: 0
, ""
, NaN
, null
, undefined
, and of course, false
(also document.all
in browsers; weird but true). All other values are truthy.