I've come across the following code:
function test(data) {
if (data != null && data !== undefined) {
// some code here
}
}
I'm somewhat new to JavaScript, but, from other questions I've been reading here, I'm under the impression that this code does not make much sense.
In particular, this answer states that
You'll get an error if you access an undefined variable in any context other than typeof.
Update: The (quote of the) answer above may be misleading. It should say «an undeclared variable», instead of «an undefined variable».
As I found out, in the answers by Ryan ♦, maerics, and nwellnhof, even when no arguments are provided to a function, its variables for the arguments are always declared. This fact also proves wrong the first item in the list below.
From my understanding, the following scenarios may be experienced:
The function was called with no arguments, thus making data an undefined variable, and raising an error on data != null.
The function was called specifically with null (or undefined), as its argument, in which case data != null already protects the inner code, rendering && data !== undefined useless.
The function was called with a non-null argument, in which case it will trivially pass both data != null and data !== undefined.
Q: Is my understanding correct?
I've tried the following, in Firefox's console:
--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true
I can't figure out a case where the data !== undefined
after data != null
might be of any use.
if (data)
. It's mnemonic Javascript way to check if data
variable evaluates to true. undefined
, null
, false, 0, empty string, empty array and (?)object with no properties evaluates to false, the rest is true.
if(data)
would mean that he can't pass false
or 0
as values for data
.
if(typeof someUndefVar == whatever) -- works
, and if(someUnderVar) -- error
.
data !== null && data !== undefined
, which is equivalent to data != null
which is equivalent to data != undefined
. The former form tends to be favored as it's more explicit about the conditions, whereas it'd be easy to overlook that both null
and undefined
are being checked with the later two conditions.
undefined
are IMO a code smell. It's not a protected keyword like null
, it's a variable that happens to be undefined. This is completely valid and is going to break your code: undefined = 1
An “undefined variable” is different from the value undefined
.
An undefined variable:
var a;
alert(b); // ReferenceError: b is not defined
A variable with the value undefined
:
var a;
alert(a); // Alerts “undefined”
When a function takes an argument, that argument is always declared even if its value is undefined
, and so there won’t be any error. You are right about != null
followed by !== undefined
being useless, though.
In JavaScript, null
is a special singleton object which is helpful for signaling "no value". You can test for it by comparison and, as usual in JavaScript, it's a good practice to use the ===
operator to avoid confusing type coercion:
var a = null;
alert(a === null); // true
As @rynah mentions, "undefined" is a bit confusing in JavaScript. However, it's always safe to test if the typeof(x)
is the string "undefined", even if "x" is not a declared variable:
alert(typeof(x) === 'undefined'); // true
Also, variables can have the "undefined value" if they are not initialized:
var y;
alert(typeof(y) === 'undefined'); // true
Putting it all together, your check should look like this:
if ((typeof(data) !== 'undefined') && (data !== null)) {
// ...
However, since the variable "data" is always defined since it is a formal function parameter, using the "typeof" operator is unnecessary and you can safely compare directly with the "undefined value".
function(data) {
if ((data !== undefined) && (data !== null)) {
// ...
This snippet amounts to saying "if the function was called with an argument which is defined and is not null..."
!= null
will be true for all values except null
and undefined
, and we’re sure that this variable is declared. typeof
in other situations can even be dangerous — what if you mistype the variable name? That can go undetected for a long time because there’s no error.
!=
at all, only strict comparison, !==
?
===
) unless you really know what you're doing and want comparison after conversion (==
).
undefined
. Also, Safari on the iPad will do that under no circumstances. You can’t even delete window.undefined
.
In your case use data==null
(which is true ONLY for null and undefined - on second picture focus on rows/columns null-undefined)
function test(data) { if (data != null) { console.log('Data: ', data); } } test(); // the data=undefined test(null); // the data=null test(undefined); // the data=undefined test(0); test(false); test('something');
Here you have all (src):
if
https://i.stack.imgur.com/uS5qE.png
== (its negation !=)
https://i.stack.imgur.com/nkpj6.png
=== (its negation !==)
https://i.stack.imgur.com/DIqvq.png
Q: The function was called with no arguments, thus making data an undefined variable, and raising an error on data != null.
A: Yes, data
will be set to undefined. See section 10.5 Declaration Binding Instantiation of the spec. But accessing an undefined value does not raise an error. You're probably confusing this with accessing an undeclared variable in strict mode which does raise an error.
Q: The function was called specifically with null (or undefined), as its argument, in which case data != null already protects the inner code, rendering && data !== undefined useless.
Q: The function was called with a non-null argument, in which case it will trivially pass both data != null and data !== undefined.
A: Correct. Note that the following tests are equivalent:
data != null
data != undefined
data !== null && data !== undefined
See section 11.9.3 The Abstract Equality Comparison Algorithm and section 11.9.6 The Strict Equality Comparison Algorithm of the spec.
data
would not exist at all, instead of being set to undefined
. I appreciate the clarification, and those references helped me understand in better detail how both equalities work.
typeof foo === "undefined"
is different from foo === undefined
, never confuse them. typeof foo === "undefined"
is what you really need. Also, use !==
in place of !=
So the statement can be written as
function (data) {
if (typeof data !== "undefined" && data !== null) {
// some code here
}
}
Edit:
You can not use foo === undefined
for undeclared variables.
var t1;
if(typeof t1 === "undefined")
{
alert("cp1");
}
if(t1 === undefined)
{
alert("cp2");
}
if(typeof t2 === "undefined")
{
alert("cp3");
}
if(t2 === undefined) // fails as t2 is never declared
{
alert("cp4");
}
foo === undefined
dangerous to use. It makes your code fails for the same condition you were trying to prevent.
foo === undefined
is perfectly acceptable in the OP's situation (assuming undefined
has not been overridden). The answer also fails to explain why !==
should be used in place of !=
.
I think, testing variables for values you do not expect is not a good idea in general. Because the test as your you can consider as writing a blacklist of forbidden values. But what if you forget to list all the forbidden values? Someone, even you, can crack your code with passing an unexpected value. So a more appropriate approach is something like whitelisting - testing variables only for the expected values, not unexpected. For example, if you expect the data value to be a string, instead of this:
function (data) {
if (data != null && data !== undefined) {
// some code here
// but what if data === false?
// or data === '' - empty string?
}
}
do something like this:
function (data) {
if (typeof data === 'string' && data.length) {
// consume string here, it is here for sure
// cleaner, it is obvious what type you expect
// safer, less error prone due to implicit coercion
}
}
The simple way to do your test is :
function (data) {
if (data) { // check if null, undefined, empty ...
// some code here
}
}
data
is a string, this test returns false on empty strings, which may, or may not, be appropriate (the function might want to deal with the empty string in some way).
""
or 0
or NaN
(or others) the "if" block will be skipped; which may or may not be OP's intent.
var a;
alert(a); //Value is undefined
var b = "Volvo";
alert(b); //Value is Volvo
var c = null;
alert(c); //Value is null
null
.
Success story sharing
data !== null && data !== undefined
would make sense, though.data != null
would check for bothnull
andundefined
(but, interestingly, just fornull
andundefined
, and not the other falsy values).