如果JavaScript中未定义变量,最合适的测试方法是什么?
我见过几种可能的方法:
if (window.myVariable)
Or
if (typeof(myVariable) != "undefined")
Or
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
如果JavaScript中未定义变量,最合适的测试方法是什么?
我见过几种可能的方法:
if (window.myVariable)
Or
if (typeof(myVariable) != "undefined")
Or
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
当前回答
我个人使用
myVar === undefined
警告:请注意==用于==,并且myVar先前已声明(未定义)。
我不喜欢myVar==“undefined”的类型。我认为这是长篇大论,没有必要。(我可以用更少的代码完成同样的任务。)
现在有些人读到这篇文章时,会痛苦万分,尖叫道:“等等!WAAITT!!!undefined可以被重新定义!”
凉的我知道这一点。同样,Javascript中的大多数变量都可以重新定义。你应该永远不要使用任何可以重新定义的内置标识符吗?
如果你遵循这条规则,对你有好处:你不是伪君子。
问题是,为了在JS中做大量的实际工作,开发人员需要依赖于可重新定义的标识符。我没有听到有人告诉我我不应该使用setTimeout,因为有人可以
window.setTimeout = function () {
alert("Got you now!");
};
总之,不使用原始==undefined的“它可以被重新定义”参数是假的。
(如果您仍然害怕未定义被重新定义,为什么要盲目地将未经测试的库代码集成到代码库中?或者更简单:一个linting工具。)
此外,与typeof方法一样,该技术可以“检测”未声明的变量:
if (window.someVar === undefined) {
doSomething();
}
但这两种技术在抽象方面都存在漏洞。我劝你不要用这个甚至
if (typeof myVar !== "undefined") {
doSomething();
}
考虑:
var iAmUndefined;
要获取该变量是否已声明,可能需要使用in运算符。(在许多情况下,您可以简单地读取代码O_O)。
if ("myVar" in window) {
doSomething();
}
但是等等!还有更多!如果一些原型连锁魔法正在发生…?现在,即使是高级操作员也不够。(好吧,我已经完成了这一部分的工作,只是说99%的时间里,==未定义(和***咳嗽***类型)工作正常。如果你真的关心,你可以单独阅读这个主题。)
其他回答
2020年更新
我倾向于检查类型(即,可以重新定义未定义的)的原因之一与ECMAScript 5的大量采用无关。另一个,你可以使用typeof来检查未声明变量的类型,总是小众的。因此,我现在建议在大多数情况下使用直接比较:
myVariable === undefined
2010年的原始答案
我喜欢使用typeof。当变量从未声明时,它将起作用,这与使用if.与==或==运算符或类型强制进行的任何比较不同(undefined,与null不同,也可能在ECMAScript 3环境中重新定义,这使得它不可靠,尽管现在几乎所有常见环境都符合ECMAScript5或更高版本)。
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
您可以使用typeof,如下所示:
if (typeof something != "undefined") {
// ...
}
就我个人而言,我总是使用以下方法:
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中使用的所有变量都应该声明。
如果未定义,它将不等于包含字符“undefined”的字符串,因为该字符串未定义。
您可以检查变量的类型:
if (typeof(something) != "undefined") ...
有时你甚至不必检查类型。如果变量的值在设置时不能求值为false(例如,如果它是一个函数),那么可以只对变量求值。例子:
if (something) {
something(param);
}
如果您有兴趣了解变量是否已声明,而不管其值如何,那么使用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
如果您想知道变量是否尚未声明或值未定义,请使用typeof运算符,它保证返回字符串:
if (typeof myVar !== 'undefined')
与undefined的直接比较很麻烦,因为undefineed可以被覆盖。
window.undefined = "foo";
"foo" == 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?
}