如何在JavaScript中检查“未定义”?[重复]

2020/09/14 18:01 · javascript ·  · 0评论

测试JavaScript中是否未定义变量的最合适方法是什么?

我已经看到了几种可能的方法:

if (window.myVariable)

要么

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

要么

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

如果您想知道变量是否已声明而无论其值如何,那么使用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')

直接比较比较undefined麻烦,因为undefined可能会被覆盖。

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

正如@CMS指出的那样,此问题已在ECMAScript第5版中进行了修补,并且undefined不可写。

if (window.myVar) 还将包含这些虚假的值,因此它不是很可靠:


0
N
空值
未定义

感谢@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?
}

我个人使用

myVar === undefined

警告:请注意,===已被使用==myVar之前已声明未定义)。


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

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

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

如果遵守此规则,对您有好处:您不是伪君子。

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

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

最重要的是,“可以重新定义”参数不使用原始=== undefined格式是虚假的。

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


同样,与该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)都可以正常工作。如果您真的很在意,可以在它自己的。)

2020更新

我偏爱typeof检查(即undefined可以重新定义)的原因之一与ECMAScript 5的大量采用无关。另一个可以typeof用来检查未声明变量类型的原因一直都是利基。因此,我现在建议在大多数情况下使用直接比较:

myVariable === undefined

2010年的原始答案

使用typeof是我的偏爱。当变量从未宣布它会的工作,不像在任何比较=====经营者或使用强制类型转换ifundefined不同于null,它可能还会在ECMAScript 3环境中重新定义,因此比较起来并不可靠,尽管现在几乎所有常见环境都符合ECMAScript 5或更高版本)。

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

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

您可以这样使用typeof

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

更新2018-07-25

自从这篇文章首次发表以来已经快五年了,JavaScript已经走了很长一段路。在重复原始帖子中的测试时,我发现以下测试方法之间没有一致的区别:

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

即使我修改了测试以防止Chrome对其进行优化,两者之间的差异也微不足道。因此,我现在建议您abc === undefined进行澄清。

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

  • Google Chrome: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

在Google Chrome浏览器中,以下内容比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

请注意,第一行以毫秒为单位,而第二行以纳秒为单位。相差3.4纳秒没什么。在随后的测试中,时间是相当一致的。

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

您可以检查变量的类型:

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

有时,您甚至不必检查类型。如果设置后变量的值不能为假(例如,如果它是一个函数),则可以对变量求值。例:

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

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

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

(请注意,在有作用域的包装器中使用varfor 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

这篇文章中我读到这样的框架Underscore.js使用此功能:

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

就个人而言,我始终使用以下内容:

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()的一个原因是,如果出现以下情况,它不会引发错误:该变量尚未定义。

我更喜欢有使用的方法

x === undefined 

因为它失败了并且炸毁了我的脸,而不是在以前没有声明过x的情况下默默地通过/失败。这提醒我未声明x。我相信应该声明JavaScript中使用的所有变量。

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

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

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

由于没有其他答案对我有帮助,我建议您这样做。它在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

}
    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 

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

我将其用作函数参数,并在函数执行时将其排除,这样我就可以得到“真实的”未定义。尽管确实需要将代码放入函数中。我在阅读jQuery源代码时发现了这一点。

undefined = 2;

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

当然,您可以使用typeof但无论如何,我的所有代码通常通常都包含在一个包含函数中,因此使用此方法可能会在这里和那里节省一些字节。

本文地址:http://javascript.askforanswer.com/ruhezaijavascriptzhongjianchaweidingyizhongfu.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!