542

I often see JavaScript code which checks for undefined parameters etc. this way:

if (typeof input !== "undefined") { // do stuff } 

This seems kind of wasteful, since it involves both a type lookup and a string comparison, not to mention its verbosity. It's needed because undefined could be renamed, though.

But there is also this approach:

if (null != input) { // do stuff } 

As far as I know, you can't redefine null, so it's not going to break unexpectedly. And, because of the type-coercion of the != operator, this checks for both undefined and null... which is often exactly what you want (e.g. for optional function parameters).

Yet this form does not seem widespread, and it even causes JSLint to yell at you for using the evil != operator.

How is using a typeof check useful beyond just checking for null != input?

12
  • 14
    @ Marcel, there is not real difference, but there are two reasons to do it. One, is that for some it is clearer to read. And the second reason, is that it prevents accidental overwriting of a variable. Have you ever done this: if( foo = "value" ) when intending to do a comparison. If you get into the habit of reversing the variable, in the assignment/comparison operator, then you won't have that problem. Commented Oct 11, 2011 at 9:14
  • 31
    For some (including me) this is actually more difficult to read. Also, most IDEs warn you of accidental assignment. But I still use this form if the compared variable is very long. YMMV. Commented Apr 4, 2012 at 7:05
  • 16
    @MarcelKorpel This is called "Yoda condition": umumble.com/blogs/Programming/321 Commented Apr 18, 2012 at 14:37
  • 57
    It's more difficult to read. One does not say "Not empty is the bottle". Commented May 7, 2012 at 9:22
  • 11
    if (null != input) is only "Yoda Speak" to the english speaker (Of one I am ....uuammmmm) so if they equate to the same thing it is really just semantics. IMHO. Commented Mar 7, 2013 at 18:30

8 Answers 8

775

typeof is safer as it allows the identifier to never have been declared before:

if(typeof neverDeclared === "undefined") // no errors if(neverDeclared === null) // throws ReferenceError: neverDeclared is not defined 
Sign up to request clarification or add additional context in comments.

18 Comments

if ((typeof neverDeclared !== "undefined") && (neverDeclared !== null)) { return true; } else { return false; }
Use === when comparing with null/undefined.
@MyGGaN only if you want to distinguish between the two. In many cases, == can be better, because it tests for both null and undefined.
I can't find any difference between typeof somevar == 'undefined' and typeof somevar === 'undefined', because typeof always returns string. For null it will return 'object'. Or could be that I am wrong?
I believe @TomTom's comment to be the crux of the problem - I can't understand why one would use the !== or === operators when comparing a value whose type is known to be a string.
|
54

If the variable is declared (either with the var keyword, as a function argument, or as a global variable), I think the best way to do it is:

if (my_variable === undefined) 

jQuery does it, so it's good enough for me :-)

Otherwise, you'll have to use typeof to avoid a ReferenceError.

If you expect undefined to be redefined, you could wrap your code like this:

(function(undefined){ // undefined is now what it's supposed to be })(); 

Or obtain it via the void operator:

const undefined = void 0; // also safe 

3 Comments

If undefined has already been defined, then wouldn't you be passing it to your anonymous function through a parameter named undefined, accomplishing nothing?
@Anthony DiSanti: No, undefined is the name given to the function parameter, not its value. Nothing is passed to the function, meaning the value of the first parameter is undefined.
Why write an exception to handle undefined being declared by another developer when you can just do it correctly to begin with? jQuery wraps the initial anonymous function as you show in your function to ensure undefined was not defined and to decrease minified size. Simply put if it can give unexpected results to do it this way, why risk it for lazy programming to avoid typing out (typeof variable === 'undefined'). What if we wanted (typeof variable === 'object') should we provide a default variable that is an object as well so we can do (variable === object)?
31

good way:

if(typeof neverDeclared == "undefined") //no errors 

But the best looking way is to check via :

if(typeof neverDeclared === typeof undefined) //also no errors and no strings 

6 Comments

var undefined = function(){}; if( typeof neverDeclared === typeof undefined ); neverDecalred != 'function'; jsfiddle.net/hbPZ5 return typeof var; returns a string. No errors or strings but will not always give expected results. Granted developers shouldn't declare undefined, but there are some frameworks and libraries that do.
I primarily use if (typeof neverDeclared === typeof undefined) { but Lint throws an error. "Expected a string and instead saw 'typeof'." How would you get around this error? Should we submit to Lint's demands and use the 'good way' instead?
@fyrye Do you know of any JavaScript libraries/frameworks that actually mutate undefined? I know it is possible; but I would like to find an in the wild example of, "Here is where you might encounter this nasty Wildebeest!"
typeof neverDeclared === typeof void 0 ;-D
It's error-prone, because in fact you're just relying on a certain variable ("undefined") not being defined. Which can be false, as other posts showed. You can always do if(typeof neverDeclared === typeof undefined_variable_with_a_name_assumed_to_be_never_defined) { but it's rather long.
|
14

You shouldn't really worry about undefined being renamed. If someone renames undefined, you will be in a lot more trouble than just a few if checks failing. If you really want to protect your code, wrap it in an IFFE (immediately invoked function expression) like this:

(function($, Backbone, _, undefined) { //undefined is undefined here. })(jQuery, Backbone, _); 

If you're working with global variables (which is wrong already) in a browser enviroment, I'd check for undefined like this:

if(window.neverDefined === undefined) { //Code works } 

Since global variables are a part of the window object, you can simply check against undefined instead of casting to a string and comparing strings.

On top of that, why are your variables not defined? I've seen a lot of code where they check a variables existence and perform some action based on that. Not once have I seen where this approach has been correct.

8 Comments

Input validation and dependency checking are both good reasons to use this. If I have Javascript files that are dependent on other files having loaded or init objects having been declared, then it's useful to test objects or properties a file is dependent on against undefined and throw a nice exception instead of letting your script fail somewhere unpredictable.
It sounds like you might need something in the lines of AMD (require.js)
Or I might just want to do a very simple comparison rather than including another library in my project :)
Too late to edit :(. Wanted to add - require.js is also not the right solution for input validation (the init objects I mentioned in my initial comment). If you've got an object that you expect to be populated with certain values before the script is loaded, then it's useful to throw an exception if they are not defined.
No, because typeof returns a string. So typeof undefined returns "undefined". window.input !== undefined (if your variable is in the global spoce)
|
5

You can also use the void operator to obtain an undefined value:

if (input !== void 0) { // do stuff } 

(And yes, as noted in another answer, this will throw an error if the variable was not declared, but this case can often be ruled out either by code inspection, or by code refactoring, e.g. using window.input !== void 0 for testing global variables or adding var input.)

Comments

3

If you are really worried about undefined being redefined, you can protect against this with some helper method like this:

function is_undefined(value) { var undefined_check; // instantiate a new variable which gets initialized to the real undefined value return value === undefined_check; } 

This works because when someone writes undefined = "foo" he only lets the name undefined reference to a new value, but he doesn't change the actual value of undefined.

8 Comments

However, you've now introduced a function call, which will harm performance.
I don't think that this function call will kill performance, it's much more likely that the DOM will be the bottleneck. But anyways, if you have your usual big anonymous function which contains your library whatever, you could also define undefined_check at the top and then just use it everywhere in your code.
Agreed, and I'm not saying this is a bad idea. It's just worth pointing out that calling this function will perform slower than doing a typeof check.
I think this function is simple enough that it would be inlined, so performance wouldn't be affected.
@TimDown: first write code, that's readable. second write code, that's maintainable, and then, if it's really to slow. then think about performance.
|
2

The two things check slightly different things:

input != null

input != null checks if a value is not null and not undefined. It is exactly the same as checking input !== null && input !== undefined

function notLooselyEqualNull(input) { const result = input != null; return `${input} not loosely equal to null: ${result}`; } console.log(notLooselyEqualNull(null)); console.log(notLooselyEqualNull(undefined)); console.log(notLooselyEqualNull(1)); console.log(notLooselyEqualNull(0)); console.log(notLooselyEqualNull("")); console.log(notLooselyEqualNull("string")); console.log(notLooselyEqualNull(false)); //more examples left as an excercise to the reader 
.as-console-wrapper { max-height: 100% !important; }

See for more details on loose equality:

But in this case only null and undefined are loosely equal to each other, therefore != null will return false for either of the two value, true for everything else.

typeof input !== "undefined"

Here the loose vs strict equality does not matter. This expression will check the type of the variable. Since it checks for the type "undefined" it will return

  • false for the value undefined (since typeof undefined returns "undefined")
  • true for everything else including null

console.log(typeof undefined !== "undefined"); console.log(typeof null !== "undefined");

The typeof check two differences to equality checks

Works with undeclared variables

The typeof check will work with undeclared variables. input == <anything> will read the value of input to use in the comparison. But when attempting to to read an identifier that was never declared with const/let/var, nor as a parameter in a function/method, nor does it exist on the global object, then attempting to read the value throws a ReferenceError:

console.log(input != null);

However, typeof will not throw error in this situation. typeof <any identifier> will return "undefined" for both an undeclared variable or a value that resolves as undefined:

const myConst = undefined; let myLet = undefined; var myVar = undefined; window.myGlobal = undefined; console.log(typeof myConst !== "undefined"); console.log(typeof myLet !== "undefined"); console.log(typeof myVar !== "undefined"); console.log(typeof myGlobal !== "undefined"); console.log(typeof myUndeclared !== "undefined");
.as-console-wrapper { max-height: 100% !important; }

Note

This is exceptionally rarely useful. Under normal circumstances you should not work with something that might be undeclared. This is a huge code smell and suggests you have done something wrong.

Occasionally you might need to run your script on a page not totally controlled by you (e.g., a userscript or inject some code), so you might need to check for the presence of something. But this is very much the exception. If you are controlling your product, then it should be deterministic whether some identifier is there or not.

Under normal circumstances you should not need to use the typeof operator to avoid reading something not yet declared.

It will correctly check the value undefined even if the identifier undefined is overwritten

Due to peculiarity, null is part of the syntax of JavaScript. It cannot be changed in any way, similar to 5 or if and other parts of the core of JavaScript.

However, undefined is not syntax. It is defined as a property of the global object. This makes it possible to change it. In earlier days it was as easy as undefined = 42, so then 42 == undefined would produce true. Nowadays, there are more restrictions but it is still possible in some situations:

function doNotTryThisAtHome(undefined) { //<-- parameter const actualUndefined = void 0; return actualUndefined != undefined; } console.log(doNotTryThisAtHome(42)); // true

However, typeof bypasses whatever undefined is set to (if anything) and directly checks the type of the value you have:

function doNotTryThisAtHome(undefined) { //<-- parameter const actualUndefined = void 0; return typeof actualUndefined !== "undefined"; } console.log(doNotTryThisAtHome(42)); // false

Note

While reading undeclared identifiers might be an extreme edge case, having undefined redefined is even more extreme of an edge case.

There is no need to try and use typeof to check for "true undefined". The reason is that for basically every non-trivial project it would be an extreme problem if undefined resolves to some other value. Throwing a typeof check here and there does not meaningfully mitigate it. Libraries will also likely use undefined checks or even direct assignments somethingNotUsedYet = undefined. Changing the value of undefined will have far reaching consequences and there is no sane way to try and handle this. At that point you are working with insane code and/or in an insane environment.

So, this usage of typeof, while entertaining, is not solving a problem.


Personal recommendation

I use != null for almost all checks. There is very rarely a reason to differentiate. When really needed !== null and !== undefined are still available but more than once being more loose with the check and treating both values the same ends up correct. It is somewhat easy for an undefined to creep in where null is expected, so something like

format number(n) { if (n !== null) return n.toFixed(2); return "0"; } 

can suddenly break. This is a real example - some utility code was checking for nulls and it worked for years, but a refactor introduced a code path where n could be undefined in some cases. However, there is no meaningful difference between the two values here, so n != null would never have thrown an error and would have always worked correctly.

Being more strict has a real chance of changing how your code works, without there needing to be a distinction.

Trying to deal with undeclared identifiers should be an extreme outlier. I can probably count on my fingers how often I have used this. And most have been various stages of hacks.

Trying to deal with undefined being redefined has not been needed since the Internet Explorer days. And even then, changing undefined could only happen from extreme sloppiness (dropping random code on your page).

Comments

0

I've actually come across if (typeof input !== 'undefined') in this scenario where it's being used to provide default function parameters:

function greet(name, greeting) { name = (typeof name !== 'undefined') ? name : 'Student'; greeting = (typeof greeting !== 'undefined') ? greeting : 'Welcome'; return `${greeting} ${name}!`; } greet(); // Welcome Student! greet('James'); // Welcome James! greet('Richard', 'Howdy'); // Howdy Richard! 

ES6 provides new ways of introducing default function parameters this way:

function greet(name = 'Student', greeting = 'Welcome') { return `${greeting} ${name}!`; } greet(); // Welcome Student! greet('James'); // Welcome James! greet('Richard', 'Howdy'); // Howdy Richard! 

This is less verbose and cleaner than the first option.

1 Comment

If you want to give a default value when name is undefined, you can also do: name = name ?? "Student";

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.