如何在JavaScript中检查“undefined”?

时间:2010-08-02 17:53:29

标签: javascript undefined

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

if (window.myVariable)

或者

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

或者

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

16 个答案:

答案 0 :(得分:2413)

如果您想知道变量是否已被声明而不管其值如何,那么使用in运算符是最安全的方法。考虑这个例子。

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

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

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

如果您有兴趣知道该变量是否尚未声明或具有值undefined,请使用typeof运算符。

if (typeof myVar !== 'undefined')

typeof运算符保证返回一个字符串。直接与undefined进行比较很麻烦,因为undefined可以被覆盖。

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

正如@CMS指出的那样,这已在ECMAScript第5版中修补,undefined是不可写的。

if (window.myVar)也会包含这些虚假值,所以它不是很强大:

false
0
""
NaN
null
undefined

感谢@CMS指出你的第三个案例 - if (myVariable)也可能在两种情况下抛出错误。第一个是未定义变量时抛出ReferenceError

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

另一种情况是定义了变量,但是有一个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?
}

答案 1 :(得分:1013)

我个人使用

myVar === undefined

警告:请注意===用于==myVar之前已宣布(不是已定义


我不喜欢typeof myVar === "undefined"。我认为这是漫长的啰嗦和不必要的。 (我可以用更少的代码完成同样的工作。)

现在有些人在读到这篇文章时会痛苦地说:“等等!WAAITTT !!! undefined可以重新定义!”

冷却。我知道这个。然后,Javascript中的大多数变量都可以重新定义。您是否应该使用任何可以重新定义的内置标识符?

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

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

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

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

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


此外,与typeof方法一样,此技术可以“检测”未声明的变量:

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

但这两种技术都在他们的抽象中泄漏。我劝你不要使用这个甚至

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

考虑:

var iAmUndefined;

要捕获是否声明了该变量,您可能需要求助于in运算符。 (在许多情况下,您只需阅读代码O_o)。

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

但是等等!还有更多!如果发生一些原型链魔术怎么办?现在即使是高级in运算符也不够。 (好吧,我在这里完成了这个部分,除了说99%的时间,=== undefined(和****咳嗽**** typeof)工作得很好。如果你非常关心,你可以自己阅读这个主题。)

答案 2 :(得分:168)

使用typeof是我的偏好。从未声明变量时它将起作用,这与使用=====运算符进行比较或使用if进行强制类型不同。 (undefinednull不同,也可以在ECMAScript 3环境中重新定义,使其不可靠进行比较,尽管现在几乎所有常见环境都符合ECMAScript 5或更高版本。

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

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

答案 3 :(得分:57)

您需要使用typeof

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

答案 4 :(得分:35)

更新2018-07-25

自这篇文章首次发布至今已近五年,JavaScript已经走过了漫长的道路。在重复原始帖子中的测试时,我发现以下测试方法之间没有一致的差异:

  • abc === undefined
  • abc === void 0
  • typeof abc == 'undefined'
  • typeof abc === 'undefined'

即使我修改了测试以阻止Chrome优化它们,但差异并不显着。因此,为了清晰起见,我现在建议abc === undefined

来自chrome://version的相关内容:

  • 谷歌浏览器:67.0.3396.99(官方版)(64位)(群组:稳定)
  • 修订版:a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs / branch-heads / 3396 @ {#790}
  • 操作系统:Windows
  • JavaScript:V8 6.7.288.46
  • 用户代理:Mozilla / 5.0(Windows NT 10.0; Win64; x64)AppleWebKit / 537.36(KHTML,与Gecko一样)Chrome / 67.0.3396.99 Safari / 537.36

原帖2013-11-01

在谷歌浏览器中,以下内容比typeof测试稍快一些:

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

差异可以忽略不计。但是,这段代码更简洁,一目了然,知道void 0意味着什么的人。但请注意,abc 仍必须声明为

typeofvoid都明显快于直接与undefined比较。我在Chrome开发者控制台中使用了以下测试格式:

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

请注意,第一行是 milli 秒,而第二行是 nano 秒。相差3.4纳秒是没有的。在随后的测试中,时间非常一致。

答案 5 :(得分:20)

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

您可以检查变量的类型:

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

有时您甚至不必检查类型。如果变量的值在设置时无法求值为false(例如,如果它是函数),那么您可以只评估变量。例如:

if (something) {
  something(param);
}

答案 6 :(得分:17)

一些场景说明了各种答案的结果: http://jsfiddle.net/drzaus/UVjM4/

(请注意,在var测试中使用in会在作用域包装中产生影响

参考代码:

(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

答案 7 :(得分:16)

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

请注意,在这种情况下不需要严格比较(!==),因为typeof将始终返回一个字符串。

答案 8 :(得分:15)

this article中,我读到像Underscore.js这样的框架使用此函数:

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

答案 9 :(得分:11)

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

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

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

我更喜欢使用

的方法
x === undefined 

因为如果之前没有声明x,它会失败并在我的脸上爆炸,而不是默默地传递/失败。这提醒我x未声明。我相信应该声明JavaScript中使用的所有变量。

答案 10 :(得分:10)

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

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

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

答案 11 :(得分:4)

由于其他答案都没有帮助我,我建议这样做。它在Internet Explorer 8中对我有用:

if (typeof variable_name.value === 'undefined') {
    // variable_name is undefined
}

答案 12 :(得分:3)

与@Thomas Eding的答案相反:

如果我忘记在代码中声明myVar,那么我将获得myVar is not defined

让我们举一个真实的例子:

我有一个变量名,但我不确定它是否在某处声明。

然后@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.");

答案 13 :(得分:3)

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

if (x === undefined) { // Throws a ReferenceError

}

答案 14 :(得分:2)

    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 

答案 15 :(得分:0)

我将它用作函数参数并在函数执行时将其排除,这样我就得到了“真正的”未定义。虽然它确实要求您将代码放在函数中。我在阅读jQuery源代码时发现了这一点。

undefined = 2;

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

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