如何检查在JavaScript中的“未定义”?

什么是testingvariables是否在JavaScript中未定义的最合适的方法? 我见过几种可能的方法:

if (window.myVariable) 

要么

 if (typeof(myVariable) != "undefined") 

要么

 if (myVariable) //This throws an error if undefined. Should this be in Try/Catch? 

如果你有兴趣找出一个variables是否已经被声明,而不pipe它的值是什么,那么使用in运算符是最安全的方法。 考虑这个例子。

 // global scope var theFu; // theFu has been declared, but its value is undefined typeof theFu; // "undefined" 

但这可能不是某些情况下的预期结果,因为声明了variables或属性,但尚未初始化。 使用in运算符进行更强大的检查。

 "theFu" in window; // true "theFoo" in window; // false 

如果您有兴趣知道该variables是否未被声明或具有undefined的值,则使用typeof运算符。

 if (typeof myVar != 'undefined') 

typeof运算符保证返回一个string。 直接比较undefined是很麻烦的,因为undefined可以被覆盖。

 window.undefined = "omg"; "omg" == undefined // true 

正如@CMS指出的,这已经在ECMAScript 5th ed。中进行了修补,而undefined是不可写的。

if (window.myVar)也将包含这些falsy值,所以它不是很健壮:

假
 0
 “”
为NaN
空值
未定义

感谢@CMS指出你的第三种情况 – if (myVariable)也可以在两种情况下抛出一个错误。 首先是当variables没有被定义的时候抛出一个ReferenceError

 // abc was never declared. if (abc) { // ReferenceError: abc is not defined } 

另一种情况是variables被定义的时候,但是有一个getter函数,当调用的时候抛出一个错误。 例如,

 // or it's a property that can throw an error Object.defineProperty(window, "myVariable", { get: function() { throw new Error("W00t?"); }, set: undefined }); if (myVariable) { // Error: W00t? } 

我个人使用

 myVar === undefined 

警告:请注意, ===用于== ,并且myVar先前已被声明未定义 )。


我不喜欢typeof myVar === "undefined" 。 我认为这是漫长而不必要的。 (我可以用较less的代码完成相同的操作。)

现在有些人在阅读时会感到很痛苦,尖叫着:“等等!哇!!!! undefined可以重新定义!”

凉。 我知道这个。 再次,Javascript中的大多数variables都可以重新定义。 你是否永远不会使用任何可以重新定义的内置标识符?

如果你遵循这个规则,对你有好处:你不是一个伪君子。

事情是,为了在JS中做大量的实际工作,开发人员需要依靠可重定义的标识符来实现它们。 我没有听到有人告诉我,我不应该使用setTimeout因为有人可以

 window.setTimeout = function () { alert("Got you now!"); }; 

底线,“可以重新定义”的参数不使用原始=== undefined是假的。

(如果你仍然害怕undefined被重新定义,为什么你盲目地将未经testing的库代码集成到你的代码库?甚至更简单:一个linting工具。)


而且,像typeof方法一样,这种技术可以“检测”未声明的variables:

 if (window.someVar === undefined) { doSomething(); } 

但是这两种技术都是抽象的。 我敦促你不要使用这个或甚至

 if (typeof myVar !== "undefined") { doSomething(); } 

考虑:

 var iAmUndefined; 

为了捕获variables是否被声明,你可能需要求助于in运算符。 (在许多情况下,你可以简单地阅读代码O_o)。

 if ("myVar" in window) { doSomething(); } 

可是等等! 还有更多! 如果有一些原型链魔法正在发生呢? 现在连运营商的高pipe也不足以胜任。 (好吧,我在这里完成了这个部分,除了说99%的时间, === undefined (和****咳嗽**** typeof )工作得很好,如果你真的关心,你可以自己阅读这个主题。)

使用typeof是我的首选。 它将在variables从未被声明的时候工作,不像任何与==或者===运算符的比较或者使用iftypes的强制转换。 ( undefined ,与null不同,也可能在ECMAScript 3环境中重新定义,使其不可靠,但几乎所有常见环境现在都符合ECMAScript 5或更高版本)。

 if (typeof someUndeclaredVariable == "undefined") { // Works } if (someUndeclaredVariable === undefined) { // Throws an error } 

你需要使用typeof

 if (typeof something != "undefined") { // ... } 

如果它是未定义的,它将不等于包含字符“undefined”的string,因为string不是未定义的。

你可以检查variables的types:

 if (typeof(something) != "undefined") ... 

有时你甚至不需要检查types。 如果variables的值在设置时不能计算为false(例如,如果它是一个函数),那么您可以只是对variables进行赋值。 例:

 if (something) { something(param); } 
 if (typeof foo == 'undefined') { // Do something }; 

请注意,在这种情况下严格比较( !== )是不必要的,因为typeof将始终返回一个string。

一些情况说明各种答案的结果: http : //jsfiddle.net/drzaus/UVjM4/

(请注意,在范围包装中使用var fortesting会有所不同)

参考编号:

 (function(undefined) { var definedButNotInitialized; definedAndInitialized = 3; someObject = { firstProp: "1" , secondProp: false // , undefinedProp not defined } // var notDefined; var tests = [ 'definedButNotInitialized in window', 'definedAndInitialized in window', 'someObject.firstProp in window', 'someObject.secondProp in window', 'someObject.undefinedProp in window', 'notDefined in window', '"definedButNotInitialized" in window', '"definedAndInitialized" in window', '"someObject.firstProp" in window', '"someObject.secondProp" in window', '"someObject.undefinedProp" in window', '"notDefined" in window', 'typeof definedButNotInitialized == "undefined"', 'typeof definedButNotInitialized === typeof undefined', 'definedButNotInitialized === undefined', '! definedButNotInitialized', '!! definedButNotInitialized', 'typeof definedAndInitialized == "undefined"', 'typeof definedAndInitialized === typeof undefined', 'definedAndInitialized === undefined', '! definedAndInitialized', '!! definedAndInitialized', 'typeof someObject.firstProp == "undefined"', 'typeof someObject.firstProp === typeof undefined', 'someObject.firstProp === undefined', '! someObject.firstProp', '!! someObject.firstProp', 'typeof someObject.secondProp == "undefined"', 'typeof someObject.secondProp === typeof undefined', 'someObject.secondProp === undefined', '! someObject.secondProp', '!! someObject.secondProp', 'typeof someObject.undefinedProp == "undefined"', 'typeof someObject.undefinedProp === typeof undefined', 'someObject.undefinedProp === undefined', '! someObject.undefinedProp', '!! someObject.undefinedProp', 'typeof notDefined == "undefined"', 'typeof notDefined === typeof undefined', 'notDefined === undefined', '! notDefined', '!! notDefined' ]; var output = document.getElementById('results'); var result = ''; for(var t in tests) { if( !tests.hasOwnProperty(t) ) continue; // bleh try { result = eval(tests[t]); } catch(ex) { result = 'Exception--' + ex; } console.log(tests[t], result); output.innerHTML += "\n" + tests[t] + ": " + result; } })(); 

和结果:

 definedButNotInitialized in window: true definedAndInitialized in window: false someObject.firstProp in window: false someObject.secondProp in window: false someObject.undefinedProp in window: true notDefined in window: Exception--ReferenceError: notDefined is not defined "definedButNotInitialized" in window: false "definedAndInitialized" in window: true "someObject.firstProp" in window: false "someObject.secondProp" in window: false "someObject.undefinedProp" in window: false "notDefined" in window: false typeof definedButNotInitialized == "undefined": true typeof definedButNotInitialized === typeof undefined: true definedButNotInitialized === undefined: true ! definedButNotInitialized: true !! definedButNotInitialized: false typeof definedAndInitialized == "undefined": false typeof definedAndInitialized === typeof undefined: false definedAndInitialized === undefined: false ! definedAndInitialized: false !! definedAndInitialized: true typeof someObject.firstProp == "undefined": false typeof someObject.firstProp === typeof undefined: false someObject.firstProp === undefined: false ! someObject.firstProp: false !! someObject.firstProp: true typeof someObject.secondProp == "undefined": false typeof someObject.secondProp === typeof undefined: false someObject.secondProp === undefined: false ! someObject.secondProp: true !! someObject.secondProp: false typeof someObject.undefinedProp == "undefined": true typeof someObject.undefinedProp === typeof undefined: true someObject.undefinedProp === undefined: true ! someObject.undefinedProp: true !! someObject.undefinedProp: false typeof notDefined == "undefined": true typeof notDefined === typeof undefined: true notDefined === undefined: Exception--ReferenceError: notDefined is not defined ! notDefined: Exception--ReferenceError: notDefined is not defined !! notDefined: Exception--ReferenceError: notDefined is not defined 

在这篇文章中,我读到像Underscore.js这样的框架使用这个函数:

 function isUndefined(obj){ return obj === void 0; } 

我知道检查undefined的最可靠的方法是使用void 0

这与新旧浏览器兼容,在某些情况下不能像window.undefined那样被覆盖。

 if( myVar === void 0){ //yup it's undefined } 

就个人而言,我总是使用以下内容:

 var x; if( x === undefined) { //Do something here } else { //Do something else here } 

在所有现代浏览器(JavaScript 1.8.5或更高版本)中,window.undefined属性是不可写的。 从Mozilla的文档: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined ,我看到这个:使用typeof()的一个原因是,它不会抛出错误,如果该variables尚未定义。

我更喜欢有使用的方法

 x === undefined 

因为它在我面前失败了,而不是默默地通过/失败,如果x没有被宣布之前。 这提醒我x没有被声明。 我相信所有在JavaScript中使用的variables都应该被声明。

在谷歌浏览器中,以下的速度比typestesting稍微快一些:

 if (abc === void 0) { // Undefined } 

差异是微不足道的。 但是,这个代码更简洁,一眼就能看清谁知道什么是void 0 。 但是请注意, abc仍然必须声明。

typeofvoid都比直接比较undefined要快得多。 我在Chrome开发者控制台中使用了以下testing格式:

 var abc; start = +new Date(); for (var i = 0; i < 10000000; i++) { if (TEST) { void 1; } } end = +new Date(); end - start; 

结果如下:

 Test: | abc === undefined abc === void 0 typeof abc == 'undefined' ------+--------------------------------------------------------------------- x10M | 13678 ms 9854 ms 9888 ms x1 | 1367.8 ns 985.4 ns 988.8 ns 

请注意,第一行以毫秒为单位,而第二行以毫微秒为单位。 3.4纳秒的差异是没有的。 在随后的testing中,时间相当一致。

由于没有其他的答案帮助我,我build议这样做。 它在Internet Explorer 8中为我工作:

 if (typeof variable_name.value === 'undefined') { // variable_name is undefined } 
 // x has not been defined before if (typeof x === 'undefined') { // Evaluates to true without errors. // These statements execute. } if (x === undefined) { // Throws a ReferenceError } 

相反@Thomas Eding回答:

如果我忘记在我的代码中声明myVar ,那么我会得到myVar is not defined

我们举一个真实的例子:

我有一个variables名,但我不确定它是否被声明在某个地方。

然后@ Anurag的答案将有助于:

 var myVariableToCheck = 'myVar'; if (window[myVariableToCheck] === undefined) console.log("Not declared or declared, but undefined."); // Or you can check it directly if (window['myVar'] === undefined) console.log("Not declared or declared, but undefined."); 
  var x; if (x === undefined) { alert ("I am declared, but not defined.") }; if (typeof y === "undefined") { alert ("I am not even declared.") }; /* One more thing to understand: typeof ==='undefined' also checks for if a variable is declared, but no value is assigned. In other words, the variable is declared, but not defined. */ // Will repeat above logic of x for typeof === 'undefined' if (x === undefined) { alert ("I am declared, but not defined.") }; /* So typeof === 'undefined' works for both, but x === undefined only works for a variable which is at least declared. */ /* Say if I try using typeof === undefined (not in quotes) for a variable which is not even declared, we will get run a time error. */ if (z === undefined) { alert ("I am neither declared nor defined.") }; // I got this error for z ReferenceError: z is not defined 

我使用它作为函数参数,并将其排除在函数执行方式,我得到的“真正”未定义。 虽然它确实需要你把你的代码放在一个函数里面。 我在阅读jQuery源代码时发现了这个问题。

 undefined = 2; (function (undefined) { console.log(undefined); // prints out undefined // and for comparison: if (undeclaredvar === undefined) console.log("it works!") })() 

当然,你可以只使用typeof 。 但是我所有的代码通常都在一个包含函数的内部,所以使用这个方法可能会节省我几个字节。