JavaScript null check

496,851

Solution 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.

Solution 2

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..."

Solution 3

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

enter image description here

== (its negation !=)

enter image description here

=== (its negation !==)

enter image description here

Solution 4

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.

Solution 5

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
  } 
}
Share:
496,851

Related videos on Youtube

afsantos
Author by

afsantos

PhD in Software Engineering

Updated on July 28, 2022

Comments

  • afsantos
    afsantos almost 2 years

    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.

    • J0HN
      J0HN about 11 years
      Just 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.
    • techfoobar
      techfoobar about 11 years
      @J0HN - Using if(data) would mean that he can't pass false or 0 as values for data.
    • afsantos
      afsantos about 11 years
      @J0HN Also, the same answer I mention also states that: if(typeof someUndefVar == whatever) -- works, and if(someUnderVar) -- error.
    • zzzzBov
      zzzzBov about 11 years
      It's probably supposed to be 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.
    • Izkata
      Izkata about 11 years
      By the way, explicit tests for 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
    • afsantos
      afsantos about 11 years
      @Izkata I've read here, on another occasion, that one should not mess up too much with undefined, as it can actually be defined, as you point out. Since then, I try to avoid mentioning undefined anywhere in my code, and, when needed, I just go for typeof, or == null.
    • uKolka
      uKolka almost 10 years
      Minor point of annoyance: "It's mnemonic Javascript," should be, "It's idiomatic Javascript."
    • Jim Jones
      Jim Jones almost 9 years
      @J0HN Boolean({}) and Boolean([]) are true.
  • bfavaretto
    bfavaretto about 11 years
    data !== null && data !== undefined would make sense, though.
  • Ry-
    Ry- about 11 years
    @bfavaretto: Yep, so it might actually be a typo. But you never know… :D
  • afsantos
    afsantos about 11 years
    Just as I thought, thanks for the clarification. Also, I do not think it's a typo. I've run a find-and-count in the whole script, and it found 10 occurrences, so... I guess the author also needs clarification on this.
  • Ry-
    Ry- about 11 years
    Okay, but the variable is declared in this case, so what’s the issue?
  • Admin
    Admin about 11 years
    Personally, I find foo === undefined dangerous to use. It makes your code fails for the same condition you were trying to prevent.
  • Ry-
    Ry- about 11 years
    Why should it look like that, though? != 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.
  • Ry-
    Ry- about 11 years
    I’m talking about the argument to the function in question. See also my other comment.
  • afsantos
    afsantos about 11 years
    @maerics So, if I followed your answer correctly, in a null check like the above scenario, you would not use != at all, only strict comparison, !==?
  • maerics
    maerics about 11 years
    @rynah: I don't presume to know enough about OP's overall solution to know if a null test is appropriate or not but I did edit to mention the fact that using "typeof" is unnecessary.
  • maerics
    maerics about 11 years
    @afsantos: in reality I don't think that many (any?) values will convert to null; however, it's a best practice to use strict comparison (===) unless you really know what you're doing and want comparison after conversion (==).
  • afsantos
    afsantos about 11 years
    Isn't this test context-dependent? I mean, if the expected type for 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).
  • maerics
    maerics about 11 years
    Except that if "data" has the value "" or 0 or NaN (or others) the "if" block will be skipped; which may or may not be OP's intent.
  • afsantos
    afsantos about 11 years
    @maerics Sure, I agree on that. Just as extra clarification, I did run more tests in the console. The only values that seem to convert to null are undefined and null itself. Running undefined == null yields true.
  • afsantos
    afsantos about 11 years
    I wasn't confusing with undeclared variables, I really didn't know how it worked when no arguments were provided. I was convinced that 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.
  • Izkata
    Izkata about 11 years
    +1 entirely for typeof(data) !== "undefined", which doesn't fall into the undefined = 1 trap
  • Izkata
    Izkata about 11 years
    Why is this being downvoted‽ The very first sentence is a correct and important distinction!
  • Matt
    Matt about 11 years
    @Izkata: because there is no explanation for the initial statement. 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 !=.
  • bfavaretto
    bfavaretto about 11 years
    Scratch my comment above: actually, data != null would check for both null and undefined (but, interestingly, just for null and undefined, and not the other falsy values).
  • Ry-
    Ry- about 11 years
    @Izkata: That trap only applies if you use Internet Explorer 8 or earlier for development, use Yoda conditionals, and use loose equality all the time. That’s a rare combination.
  • Izkata
    Izkata about 11 years
    @rynah We still have to support IE6 for our clients, this became known as a trap because at one time it was abused in a JS library, and Safari on the iPad throws javascript exceptions in certain situations relating to it not being a keyword: undefined is undefined. So all in all, I still say, don't rely on it.
  • Ry-
    Ry- about 11 years
    @Izkata: Drop any library that attempts to redefine undefined. Also, Safari on the iPad will do that under no circumstances. You can’t even delete window.undefined.
  • Kadiri
    Kadiri about 11 years
    Sorry @afsantos, I didn't saw your comment, if you want to get false when data is undefined, null ... except when date is an empty, you'll need to create an other var toTest = data; with an other test after the first one like : if(toTest=="") { // some code here }
  • Ry-
    Ry- almost 10 years
    Please add some explanation as to what this is supposed to mean.
  • Sebastian Simon
    Sebastian Simon about 8 years
    This doesn’t really check for null.