在 JavaScript 中测试变量是否未定义的最合适方法是什么?
我已经看到了几种可能的方法:
if (window.myVariable)
或者
if (typeof(myVariable) != "undefined")
或者
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
在 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
如果您想知道变量是否尚未声明或具有 value undefined
,请使用typeof
运算符,它保证返回一个字符串:
if (typeof myVar !== 'undefined')
直接比较比较undefined
麻烦,因为undefined
可以覆盖。
window.undefined = "foo";
"foo" == undefined // true
正如@CMS 所指出的,这已在 ECMAScript 第 5 版中进行了修补,并且undefined
是不可写的。
if (window.myVar)
还将包括这些虚假值,因此它不是很健壮:
错误的 0 “” NaN 空值 不明确的
感谢@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
警告:请注意,===
使用 over==
并且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
(和 ****cough**** typeof
)工作得很好。如果你真的关心,你可以阅读关于这个主题它自己的。)
2020 更新
我更喜欢typeof
检查(即undefined
可以重新定义)的一个原因与 ECMAScript 5 的大规模采用无关。另一个,您可以typeof
用来检查未声明变量的类型,始终是小众的。因此,我现在建议在大多数情况下使用直接比较:
myVariable === undefined
2010年的原始答案
使用typeof
是我的偏好。当变量从未被声明时它将起作用,这与使用==
或===
运算符或类型强制的任何比较不同if
。(undefined
与 不同null
,它也可能在 ECMAScript 3 环境中重新定义,因此比较不可靠,尽管现在几乎所有常见环境都符合 ECMAScript 5 或更高版本)。
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
你可以使用typeof
,像这样:
if (typeof something != "undefined") {
// ...
}
这篇博文从第一次发布到现在已经快五年了,JavaScript 已经走过了漫长的道路。在重复原帖中的测试时,我发现以下测试方法之间没有一致的差异:
abc === undefined
abc === void 0
typeof abc == 'undefined'
typeof abc === 'undefined'
即使我修改了测试以防止 Chrome 优化它们,差异也很小。因此,abc === undefined
为了清楚起见,我现在建议。
相关内容来自chrome://version
:
在谷歌浏览器中,以下比typeof
测试稍微快一点:
if (abc === void 0) {
// Undefined
}
差异可以忽略不计。但是,这段代码更简洁,对于知道void 0
含义的人来说更清晰。但是请注意,abc
仍然必须声明。
双方typeof
并void
分别显著快于对直接比较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 纳秒的差异不算什么。在随后的测试中,时间非常一致。