开发者

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

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

if (typeof input !开发者_如何学Go== "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?


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


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


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.


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.


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


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.


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!


(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


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


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜