ChatGPT解决这个技术问题 Extra ChatGPT

typeof !== "undefined" vs. != null

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?

@ 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.
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.
@MarcelKorpel This is called "Yoda condition": umumble.com/blogs/Programming/321
It's more difficult to read. One does not say "Not empty is the bottle".
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.

J
Josh Wood

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

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.
F
FZs

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

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.
Ah my mistake, thanks for following up. I've removed my vote down, sorry about that.
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)?
j
jNayden

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

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.
P
Peeter

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.


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)
I
Ivo Wetzel

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.


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.
C
Claude

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


J
JSpecs

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.


A
Avinash Maurya

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!


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.
A
Avinash Maurya

(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("
* oprator as math "); var r=14*"4"; document.write(r); document.write("
+ oprator as string "); var r=14+"44"; document.write(r); document.write("
Minus Operator work as mathematic "); var r=64-"44"; document.write(r); document.write("
"); console.log(typeof(4*"7")); //returns number console.log(typeof(4+"7")); //returns string Interview Question in JavaScript


Can you provide an explanation?
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)
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.
A
Avinash Maurya

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


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.
k
kapa
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?


Your input == undefined will return true on a null input.