测试 JavaScript 中是否未定义变量的最合适方法是什么?
我见过几种可能的方法:
if (window.myVariable)
或者
if (typeof(myVariable) != "undefined")
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
如果您有兴趣找出变量是否已被声明而不管其值如何,那么使用in运算符是最安全的方法。考虑这个例子:
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运算符,它保证返回一个字符串:
undefined
typeof
if (typeof myVar !== 'undefined')
直接比较undefined很麻烦,因为undefined可能会被覆盖。
window.undefined = "foo"; "foo" == undefined // true
正如@CMS 所指出的,这已在 ECMAScript 第 5 版中进行了修补,并且undefined是不可写的。
if (window.myVar) 还将包括这些虚假值,因此它不是很健壮:
if (window.myVar)
false 0 "" NaN null undefined
感谢@CMS 指出您的第三种情况 -if (myVariable)在两种情况下也可能引发错误。第一个是当变量尚未定义时,它会抛出一个ReferenceError.
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先前已声明(未定义)。
===
==
myVar
我不喜欢typeof myVar === "undefined"。我认为这是冗长而不必要的。(我可以用更少的代码完成同样的工作。)
typeof myVar === "undefined"
现在有些人看到这里会痛得头晕目眩,尖叫:“等等!WAAITTT!!!undefined可以重新定义!”
凉爽的。我知道这个。再说一遍,Javascript 中的大多数变量都可以重新定义。你不应该使用任何可以重新定义的内置标识符吗?
如果你遵循这条规则,对你有好处:你不是伪君子。
问题是,为了在 JS 中做大量实际工作,开发人员需要依赖可重新定义的标识符才能成为他们的样子。我没有听到人们告诉我我不应该使用setTimeout,因为有人可以
setTimeout
window.setTimeout = function () { alert("Got you now!"); };
最重要的是,不使用原始的“它可以重新定义”的论点=== undefined是虚假的。
=== 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)工作得很好。如果你真的在乎,你可以阅读关于这个主题的内容它自己的。)