typeof!==“undefined”vs.!= null

时间:2010-04-24 03:26:13

标签: javascript coding-style

我经常看到JavaScript代码以这种方式检查未定义的参数:

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

这似乎有点浪费,因为它涉及类型查找和字符串比较,更不用说它的冗长。这是必要的,因为'undefined'可以重命名。我的问题是:代码如何比这种方法更好:

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

据我所知,你不能重新定义null,所以它不会意外地破坏。并且,由于!=运算符的类型强制,这将检查undefined和null ...这通常正是您想要的(例如,对于可选的函数参数)。然而,这种形式似乎并不普遍,它甚至会导致JSLint对你使用邪恶!=运算符大喊大叫。为什么这被认为是不好的风格?

11 个答案:

答案 0 :(得分:664)

typeof更安全,因为它允许标识符从未在之前声明过:

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

if(neverDeclared === null) // throws ReferenceError: neverDeclared is not defined

答案 1 :(得分:47)

如果声明变量(使用var关键字,作为函数参数或作为全局变量),我认为最好的方法是:

if (my_variable === undefined)

jQuery做到了,所以它对我来说足够好了: - )

否则,您必须使用typeof来避免ReferenceError

如果您希望重新定义undefined,可以像这样包装代码:

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

答案 2 :(得分:26)

好方法:

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

但最好的方法是检查通过:

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

答案 3 :(得分:12)

你不应该真的担心未定义的重命名。如果某人重命名未定义,那么如果检查失败,您将遇到的问题远不止一些。如果你真的想要保护你的代码,请将它包装在IFFE(立即调用的函数表达式)中,如下所示:

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

如果你在浏览器环境中使用全局变量(这已经是错误的),我会检查这样的未定义:

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

由于全局变量是窗口对象的一部分,因此您只需检查undefined而不是转换为字符串并比较字符串。

最重要的是,为什么你的变量没有定义?我看过很多代码,他们检查变量是否存在,并根据它执行一些操作。我没有看到这种方法在哪里是正确的。

答案 4 :(得分:6)

如果你真的担心未定义被重新定义,你可以用这样的帮助方法来防止这种情况:

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

这是有效的,因为当有人写undefined = "foo"时,他只允许名称 undefined引用新值,但他不会更改{{1}的实际值}}

答案 5 :(得分:4)

您还可以使用void运算符来获取未定义的值:

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

(是的,如另一个答案中所述,如果未声明变量,这将引发错误,但这种情况通常可以通过代码检查或代码重构来排除,例如使用window.input !== void 0用于测试全局变量或添加var input。)

答案 6 :(得分:1)

如果(typeof input !== 'undefined')在这个场景中被用来提供默认的功能参数,我实际上遇到过:

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以这种方式提供了引入默认函数参数的新方法:

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

greet(); // Welcome Student!
greet('James'); // Welcome James!
greet('Richard', 'Howdy'); // Howdy Richard!

这比第一个选项更简洁,更清晰。

答案 7 :(得分: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!

答案 8 :(得分: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

答案 9 :(得分: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

答案 10 :(得分:-7)

if (input == undefined) { ... }

工作得很好。这当然不是null比较,但我通常会发现,如果我需要区分undefinednull,我实际上需要区分undefined和任何错误的价值,所以

else if (input) { ... }

做到了。

如果某个程序重新定义undefined,那么无论如何它都是真正的脑力。

我能想到的唯一原因是IE4兼容性,它不理解undefined关键字(不幸的是,它实际上不是关键字),但当然值 undefined,所以你必须拥有这个:

var undefined;

上面的比较就可以了。

在你的第二个例子中,你可能需要双括号才能让lint满意吗?