511

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.

My question is:
How is that code any better than 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.

Why is this considered bad style?

FZs
  • 11,931
  • 11
  • 28
  • 41
Derek Thurn
  • 13,971
  • 9
  • 35
  • 54
  • 1
    Why did you change `if (input != null)` to `if (null != input)`? What's the difference? – Marcel Korpel Apr 24 '10 at 10:17
  • 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. – Layke Oct 11 '11 at 09:14
  • 29
    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. – johndodo Apr 04 '12 at 07:05
  • 16
    @MarcelKorpel This is called "Yoda condition": http://umumble.com/blogs/Programming/321 – kol Apr 18 '12 at 14:37
  • 55
    It's more difficult to read. One does not say "Not empty is the bottle". – Noel Abrahams May 07 '12 at 09:22
  • 2
    In general I prefer code that's easier to read, but I also prefer conditions to be written this way. I argue @Marcel's form is superior. To me it's more concise to say "a value isn't equal to a variable" than the traditional way of writing which is prone to error as Marcel illustrates. In terms of empty that means "empty is not the bottle". Perhaps it's the mathematician in me. – Tenacious Sep 24 '12 at 20:21
  • 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. – webLacky3rdClass Mar 07 '13 at 18:30
  • 4
    The real issue is the question shouldn't have been edited for a coding style. e.g., I would never name a variable 'input', but I'm not going to edit the question to change it. – goodeye Feb 28 '14 at 17:09
  • 2
    @NoelAbrahams If you even once have to track down an accidental assignment in a conditional, you'll see the virtue of if (null != x). We don't use recursion or trinary operators in English either, but they're worth learning to read. – Spike0xff Jan 20 '15 at 22:16
  • @Spike0xff you advise using reversed syntax like this, but also promote using recursion and ternary operators? writing code is not for everybody, you shouldn't need to go to such great lengths to ensure the cleaning lady won't lose 5 minutes tracking down an accidental assignment. – Buffalo Sep 11 '17 at 07:49
  • If you're really worried about performance and looks, just do this... `if (input)`. This will only return true if `input` is defined and... (1) is a non-null value (2) not 0 (3) not an empty string and (4) not the boolean value `false`. Otherwise, if you just want to check that the variable is defined, `typeof` is the best option. – A-Diddy Nov 07 '19 at 16:41

11 Answers11

730

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
Josh Wood
  • 421
  • 3
  • 13
seanmonstar
  • 10,888
  • 2
  • 19
  • 25
  • 3
    if ((typeof neverDeclared !== "undefined") && (neverDeclared !== null)) { return true; } else { return false; } – Anthony DiSanti Oct 24 '10 at 21:00
  • 91
    Use === when comparing with null/undefined. – MyGGaN Jun 15 '12 at 12:38
  • 53
    @MyGGaN only if you want to distinguish between the two. In many cases, `==` can be better, because it tests for both null and undefined. – seanmonstar Jun 19 '12 at 16:58
  • 10
    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? – TomTom Feb 01 '13 at 14:55
  • 2
    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. – Nicolas Rinaudo Aug 30 '13 at 07:38
  • 1
    @TomTom is right - in case of typeof comparison, == and === will give the same results. See http://symfony-world.blogspot.com/2013/07/javascript-datatypes.html for more about typeof (and instanceof) – ducin Oct 23 '13 at 19:39
  • 2
    Don't use typeof operator when checking for undefined variable. It is just not readable. When you need to check global variable which might throw an error, just write it with global object-like this in browsers: if(window.neverDeclared === undefined){} – Capaj Jun 12 '14 at 08:57
  • 1
    @Capaj I disagree with the readability argument, not that my opinion matters. But you present an interesting alternative if we're only working with global variables. In any other case, we _must_ use typeof to avoid errors, yes? – thekingoftruth Jul 14 '14 at 20:12
  • @thekingoftruth well when I want to know if some property of an object is undefined, I already suppose the object exists, therefore I can write it as: if(myObj.prop === undefined){} If myObj does not exist, both conditions(mine and typeof equality) will throw same error, so style advised in this answer does not have any considerable advantage. – Capaj Jul 14 '14 at 23:39
  • So either check typeof foo == 'undefined' and foo == null is doing the same thing except you will get a error for check if it is null? – tom10271 Sep 02 '14 at 09:51
  • @Capaj, actually you can declare undefined as an actual variable: try var undefined = "now i'm a string!"; – mydoglixu May 01 '15 at 15:52
  • @mydoglixu In modern browsers initializing this way does nothing - it will still return the "undefined" value. – rgripper Jun 02 '15 at 07:20
  • 1
    @rgripper, there have been some changes lately, and while you're correct, we should stick with best practices and address this backwards as well, i.e. use typeof instead – mydoglixu Jun 02 '15 at 14:21
  • @mydoglixu Clear code should be preferred unless otherwise. The only reasons for that legacy check are a usage of legacy libraries or expectation that script will be used by an external developer. Most devs should not worry about that IMO. – rgripper Jun 02 '15 at 15:20
  • @seanmonstar How do I know that you meant to check for both and didn't make a mistake? If you want to check for both `null` and `undefined` the code should be clear about it. If there is a comment to explain that both are meant, you might as well have written both conditions out in full in the first place. – CJ Dennis Aug 11 '17 at 01:25
  • [Well, if you're using ES6 stuff like `let` or `const`, **`typeof` is no longer _safe_.**](http://es-discourse.com/t/why-typeof-is-no-longer-safe/15) `if(true) {typeof x; let x;}` throws a `ReferenceError`. – Константин Ван Apr 08 '18 at 06:43
  • 1
    Putting the constant first like this: `if( null == neverDeclared )` (or `if( null === neverDeclared )`) prevents the not-so-obvious mistakes like this: `if( neverDeclared = null )` #GoodCodingPractice – Dev Null Nov 16 '18 at 21:30
  • For those who still find the string literal icky, if the never-declared identifier is expected to exist in global scope you can write `!!window["neverDeclared"]` instead. – Extragorey Dec 02 '19 at 03:45
49

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
FZs
  • 11,931
  • 11
  • 28
  • 41
Joey Adams
  • 37,814
  • 17
  • 79
  • 110
  • 1
    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 Oct 24 '10 at 21:05
  • 20
    @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. – Joey Adams Oct 24 '10 at 22:33
  • 3
    Ah my mistake, thanks for following up. I've removed my vote down, sorry about that. – Anthony DiSanti Nov 01 '10 at 18:47
  • 2
    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)? – Will B. Jan 19 '14 at 01:28
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
JOKe
  • 1,532
  • 1
  • 16
  • 28
  • 6
    var undefined = function(){}; if( typeof neverDeclared === typeof undefined ); neverDecalred != 'function'; http://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. – Will B. Jan 19 '14 at 00:55
  • 1
    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? – Ayelis May 12 '15 at 00:45
  • 2
    @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!" – bigtunacan Sep 08 '15 at 20:09
  • 4
    `typeof neverDeclared === typeof void 0` ;-D – Alex Yaroshevich Apr 10 '17 at 13:09
  • 1
    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. – Pierre-Olivier Vares Aug 11 '17 at 11:31
  • You guys.... this will only work until the variable `undefined` is actually defined. You're essentially comparing the output of `typeof` to the output of another `typeof`, which is misleading. – A-Diddy Nov 07 '19 at 16:34
13

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.

Peeter
  • 8,952
  • 4
  • 34
  • 52
  • 1
    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. – AmericanUmlaut Jan 23 '13 at 14:01
  • It sounds like you might need something in the lines of AMD (require.js) – Peeter Jan 23 '13 at 14:31
  • 1
    Or I might just want to do a very simple comparison rather than including another library in my project :) – AmericanUmlaut Jan 23 '13 at 14:43
  • 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. – AmericanUmlaut Jan 23 '13 at 14:54
  • Does using this method means you can use 'typeof input !== undefined'? Without the quotes around undefined because no one would have renamed it? – Christopher Grigg Sep 18 '15 at 05:59
  • 1
    No, because typeof returns a string. So typeof undefined returns "undefined". window.input !== undefined (if your variable is in the global spoce) – Peeter Sep 18 '15 at 08:03
  • //undefined is undefined here. I'm new to JavaScript. What does that mean? – Ilyas karim Mar 22 '17 at 19:00
  • In JavaScript, every function has its own scope. The IIFE is called with 3 references, but it accepts 4 arguments, and the 4th is named `undefined`. Since only 3 parameters are being passed to that function, the 4th is automatically assigned the primitive value `undefined`. Peeter is doing this so that even if someone has assigned a different value to the variable `undefined` somewhere else, it will still definitely have the primitive value of `undefined` in the scope of this function. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined#Description – Donutself Jul 01 '18 at 21:16
5

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.

Ivo Wetzel
  • 44,463
  • 14
  • 89
  • 109
  • 1
    However, you've now introduced a function call, which will harm performance. – Tim Down Apr 26 '10 at 08:56
  • 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. – Ivo Wetzel Apr 26 '10 at 12:30
  • 1
    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. – Tim Down Apr 26 '10 at 13:27
  • I think this function is simple enough that it would be inlined, so performance wouldn't be affected. – huyz Sep 06 '11 at 15:33
  • 5
    @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. – andreas Nov 15 '13 at 10:57
  • @andreas: No arguments from me about that. I think I was careful to merely make the point about performance without actually making any recommendation. – Tim Down Nov 15 '13 at 11:47
  • You could use `void 0` in place of your variable, as well. – natevw May 26 '14 at 18:13
  • Wouldn't it still work only for variables that have been explicitly declared? For example, if I'm waiting for my code to check if a function is defined, it will still result out in an error. – Piyush Soni Apr 07 '15 at 15:35
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.)

Claude
  • 67
  • 1
  • 2
2

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.

JSpecs
  • 95
  • 1
  • 8
1

function greet(name, greeting) {
  name = (typeof name !== 'undefined') ?  name : 'Student';
  greeting = (typeof greeting !== 'undefined') ?  greeting : 'Welcome';

  console.log(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 greet2(name = 'Student', greeting = 'Welcome') {
//  return '${greeting} ${name}!';
console.log(greeting,name);
}

greet2(); // Welcome Student!
greet2('James'); // Welcome James!
greet2('Richard', 'Howdy'); // Howdy Richard!
Avinash Maurya
  • 252
  • 2
  • 4
  • 1) You do not need to answer the same question 3 times. 2) An answer consisting solely of code is a poor answer. You need to explain ... in English ... and relate the answer to the question asked. 3) Most of the code in your answer is irrelevant to the question. – Stephen C Nov 07 '20 at 10:25
0

(function(){

  var a= b = 3;
  var ed = 103;
  
})();



//console.log(ed); //ed is not defined

console.log("a defined? " + (typeof a !== 'undefined')); //no define
console.log("b defined? " + (typeof b !== 'undefined')); //yes define
console.log(typeof(b)); //number
console.log(typeof(4+7));   //number
console.log(b); //3
console.log(typeof("4"+"7")); //string
var e= "ggg";
console.log(typeof(e)); //string
 var ty=typeof(b);
console.log(ty); //number
console.log(typeof false); //boolean
console.log(typeof 1); //number
console.log(typeof 0); //number
console.log(typeof true); //boolean


console.log(typeof Math.tan);  //function
console.log(typeof function(){}); //function 

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

//if(neverDeclared == null) //showing error 


console.log(typeof {a:1}); //object
console.log(typeof null); //object
console.log(typeof JSON); //object
console.log(typeof Math); //object
console.log(typeof /a-z/); //object
console.log(typeof new Date()); //object

console.log(typeof afbc); //undefined
//console.log(typeof new);//error

document.write("<br> * oprator as math ");
var r=14*"4";
document.write(r);

document.write("<br> + oprator as string ");
var r=14+"44";
document.write(r);

document.write("<br> Minus Operator work as mathematic ");
var r=64-"44";
document.write(r);


document.write("<br>");
console.log(typeof(4*"7")); //returns number
console.log(typeof(4+"7")); //returns string




 
Interview Question in JavaScript
Avinash Maurya
  • 252
  • 2
  • 4
  • Can you provide an explanation? – jhpratt Sep 13 '18 at 01:43
  • There are six possible values that typeof returns: object, boolean, function, number, string, and undefined. The typeof operator is used to get the data type (returns a string) of its operand. The operand can be either a literal or a data structure such as a variable, a function, or an object. The operator returns the data type. Syntax typeof operand or typeof (operand) – Avinash Maurya Sep 13 '18 at 01:51
  • 1) You do not need to answer the same question 3 times. 2) An answer consisting solely of code is a poor answer. You need to explain ... in English ... and relate the answer to the question asked. 3) Most of the code in your answer is irrelevant to the question. – Stephen C Nov 07 '20 at 10:25
0

var bar = null;
console.log(typeof bar === "object"); //true yes 
//because null a datatype of object

var barf = "dff";
console.log(typeof barf.constructor);//function


console.log(Array.isArray(bar));//falsss


console.log((bar !== null) && (bar.constructor === Object)); //false

console.log((bar !== null) && (typeof bar === "object"));  // logs false
//because bar!==null, bar is a object


console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function"))); //false

console.log(typeof bar === typeof object); //false
console.log(typeof bar2 === typeof undefined); //true
console.log(typeof bar3 === typeof undefinedff); //true
console.log(typeof bar2 == typeof undefined); //true

console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]")); //false
Avinash Maurya
  • 252
  • 2
  • 4
  • 1) You do not need to answer the same question 3 times. 2) An answer consisting solely of code is a poor answer. You need to explain ... in English ... and relate the answer to the question asked. 3) Most of the code in your answer is irrelevant to the question. – Stephen C Nov 07 '20 at 10:25
-7
if (input == undefined) { ... }

works just fine. It is of course not a null comparison, but I usually find that if I need to distinguish between undefined and null, I actually rather need to distinguish between undefined and just any false value, so

else if (input) { ... }

does it.

If a program redefines undefined it is really braindead anyway.

The only reason I can think of was for IE4 compatibility, it did not understand the undefined keyword (which is not actually a keyword, unfortunately), but of course values could be undefined, so you had to have this:

var undefined;

and the comparison above would work just fine.

In your second example, you probably need double parentheses to make lint happy?

kapa
  • 72,859
  • 20
  • 152
  • 173