关于javascript:typeof!==“undefined”vs.!= null

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

我经常看到检查未定义参数等的javascript代码。这样:

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

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

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

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


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

1
2
3
if(typeof neverDeclared ==="undefined") // no errors

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


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

1
if (my_variable === undefined)

jquery做到了,所以对我来说已经足够好了:-)

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

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

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


好方法:

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

但最好的方法是通过以下途径进行检查:

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


你不必担心未定义的被重命名。如果有人重命名未定义,那么如果检查失败,您将面临比仅几个更大的麻烦。如果您真的想保护您的代码,请将其包装在iffe(立即调用的函数表达式)中,如下所示:

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

如果您在浏览器环境中使用全局变量(已经是错误的),我将检查未定义的,如下所示:

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

因为全局变量是window对象的一部分,所以您可以简单地检查未定义的变量,而不是强制转换为字符串并比较字符串。

除此之外,为什么没有定义变量?我见过很多代码,它们检查变量的存在并基于此执行一些操作。我从未见过这种方法的正确之处。


如果您真的担心未定义被重新定义,您可以使用如下辅助方法来防止这种情况:

1
2
3
4
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引用一个新值,但他不改变undefined的实际值。


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

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

(是的,正如另一个答案所指出的那样,如果变量没有声明,这将抛出一个错误,但这种情况通常可以通过代码检查或代码重构排除,例如使用window.input !== void 0测试全局变量或添加var input)。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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!


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

1
2
3
4
5
6
7
8
9
10
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提供了引入默认函数参数的新方法:

1
2
3
4
5
6
7
function greet(name = 'Student', greeting = 'Welcome') {
  return `${greeting} ${name}!`;
}

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

这比第一个选项更详细、更清晰。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(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
1
Interview Question in JavaScript


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

工作很好。当然,这不是一个null比较,但我通常会发现,如果我需要区分undefinednull的话,我实际上更需要区分undefined和任何虚假值,所以

1
else if (input) { ... }

做到了。

如果一个程序重新定义了undefined,那么不管怎样,它真的是脑死亡。

我能想到的唯一原因是为了IE4的兼容性,它不理解undefined关键字(不幸的是,它实际上不是关键字),但当然值可以是undefined,所以您必须具备:

1
var undefined;

上面的比较就可以了。

在第二个例子中,您可能需要双括号来让lint高兴?