如何在 JavaScript 中检查“未定义”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3390396/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check for "undefined" in JavaScript?
提问by goodguys_activate
What is the most appropriate way to test if a variable is undefined in JavaScript? I've seen several possible ways:
在 JavaScript 中测试变量是否未定义的最合适方法是什么?我已经看到了几种可能的方法:
if (window.myVariable)
Or
或者
if (typeof(myVariable) != "undefined")
Or
或者
if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?
回答by Anurag
If you are interested in finding out whether a variable has been declared regardless of its value, then using the inoperator is the safest way to go. Consider this example:
如果您想知道变量是否已被声明而不管其值如何,那么使用in运算符是最安全的方法。考虑这个例子:
// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"
But this may not be the intended result for some cases, since the variable or property was declared but just not initialized. Use the inoperator for a more robust check.
但这在某些情况下可能不是预期的结果,因为变量或属性已声明但未初始化。使用in运算符进行更可靠的检查。
"theFu" in window; // true
"theFoo" in window; // false
If you are interested in knowing whether the variable hasn't been declared or has the value undefined, then use the typeofoperator, which is guaranteed to return a string:
如果您想知道变量是否尚未声明或具有 value undefined,请使用typeof运算符,它保证返回一个字符串:
if (typeof myVar !== 'undefined')
Direct comparisons against undefinedare troublesome as undefinedcan be overwritten.
直接比较比较undefined麻烦,因为undefined可以覆盖。
window.undefined = "foo";
"foo" == undefined // true
As @CMS pointed out, this has been patched in ECMAScript 5th ed., and undefinedis non-writable.
正如@CMS 所指出的,这已在 ECMAScript 第 5 版中进行了修补,并且undefined是不可写的。
if (window.myVar)will also include these falsy values, so it's not very robust:
if (window.myVar)还将包括这些虚假值,所以它不是很健壮:
false 0 "" NaN null undefined
Thanks to @CMS for pointing out that your third case - if (myVariable)can also throw an error in two cases. The first is when the variable hasn't been defined which throws a ReferenceError.
感谢@CMS 指出您的第三种情况 -if (myVariable)也可能在两种情况下引发错误。第一个是当变量没有被定义时抛出一个ReferenceError.
// abc was never declared.
if (abc) {
// ReferenceError: abc is not defined
}
The other case is when the variable has been defined, but has a getter function which throws an error when invoked. For example,
另一种情况是变量已定义,但有一个 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?
}
回答by Thomas Eding
I personally use
我个人使用
myVar === undefined
Warning: Please note that ===is used over ==and that myVarhas been previously declared(not defined).
警告:请注意,===使用 over==并且myVar之前已声明(未定义)。
I do not like typeof myVar === "undefined". I think it is long winded and unnecessary. (I can get the same done in less code.)
我不喜欢typeof myVar === "undefined"。我认为这是冗长且不必要的。(我可以用更少的代码完成同样的事情。)
Now some people will keel over in pain when they read this, screaming: "Wait! WAAITTT!!! undefinedcan be redefined!"
现在有些人读到这里会痛苦地倒下,尖叫:“等等!WAAITTT!!!undefined可以重新定义!”
Cool. I know this. Then again, most variables in Javascript can be redefined. Should you never use any built-in identifier that can be redefined?
凉爽的。我知道这个。再说一次,Javascript 中的大多数变量都可以重新定义。你应该永远不要使用任何可以重新定义的内置标识符吗?
If you follow this rule, good for you: you aren't a hypocrite.
如果你遵循这条规则,对你有好处:你不是一个伪君子。
The thing is, in order to do lots of real work in JS, developers need to rely on redefinable identifiers to be what they are. I don't hear people telling me that I shouldn't use setTimeoutbecause someone can
问题是,为了在 JS 中完成大量实际工作,开发人员需要依赖可重新定义的标识符来实现它们的本质。我没有听到人们告诉我我不应该使用,setTimeout因为有人可以
window.setTimeout = function () {
alert("Got you now!");
};
Bottom line, the "it can be redefined" argument to not use a raw === undefinedis bogus.
最重要的是,不使用原始数据的“它可以重新定义”的论点=== undefined是虚假的。
(If you are still scared of undefinedbeing redefined, why are you blindly integrating untested library code into your code base? Or even simpler: a linting tool.)
(如果你仍然害怕undefined被重新定义,你为什么盲目地将未经测试的库代码集成到你的代码库中?或者甚至更简单:一个 linting 工具。)
Also, like the typeofapproach, this technique can "detect" undeclared variables:
此外,与该typeof方法一样,该技术可以“检测”未声明的变量:
if (window.someVar === undefined) {
doSomething();
}
But both these techniques leak in their abstraction. I urge you not to use this or even
但是这两种技术都在抽象中泄漏。我敦促你不要使用这个甚至
if (typeof myVar !== "undefined") {
doSomething();
}
Consider:
考虑:
var iAmUndefined;
To catch whether or not that variable is declared or not, you may need to resort to the inoperator. (In many cases, you can simply read the code O_o).
要了解该变量是否已声明,您可能需要求助于in运算符。(在很多情况下,你可以简单地阅读代码O_o)。
if ("myVar" in window) {
doSomething();
}
But wait! There's more! What if some prototype chain magic is happening…? Now even the superior inoperator does not suffice. (Okay, I'm done here about this part except to say that for 99% of the time, === undefined(and ****cough**** typeof) works just fine. If you really care, you can read about this subject on its own.)
可是等等!还有更多!如果某些原型链魔法正在发生怎么办……?现在即使是优秀的in运营商也不够。(好吧,我已经完成了这部分的工作,只是说在 99% 的时间里,=== undefined(和 ****cough**** typeof)工作得很好。如果你真的关心,你可以阅读关于这个主题的它自己的。)
回答by Tim Down
2020 Update
2020 更新
One of my reasons for preferring a typeofcheck (namely, that undefinedcan be redefined) became irrelevant with the mass adoption of ECMAScript 5. The other, that you can use typeofto check the type of an undeclared variable, was always niche. Therefore, I'd now recommend using a direct comparison in most situations:
我更喜欢typeof检查(即undefined可以重新定义)的一个原因与 ECMAScript 5 的大规模采用无关。另一个,您可以typeof用来检查未声明变量的类型,始终是小众的。因此,我现在建议在大多数情况下使用直接比较:
myVariable === undefined
Original answer from 2010
2010年的原始答案
Using typeofis my preference. It will work when the variable has never been declared, unlike any comparison with the ==or ===operators or type coercion using if. (undefined, unlike null, may also be redefined in ECMAScript 3 environments, making it unreliable for comparison, although nearly all common environments now are compliant with ECMAScript 5 or above).
使用typeof是我的偏好。当变量从未被声明时,它将起作用,这与使用==或===运算符或类型强制的任何比较不同if。(undefined与 不同null,它也可能在 ECMAScript 3 环境中重新定义,因此比较不可靠,尽管现在几乎所有常见环境都符合 ECMAScript 5 或更高版本)。
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
回答by Jacob Relkin
You can use typeof, like this:
你可以使用typeof,像这样:
if (typeof something != "undefined") {
// ...
}
回答by Zenexer
Update 2018-07-25
更新 2018-07-25
It's been nearly five years since this post was first made, and JavaScript has come a long way. In repeating the tests in the original post, I found no consistent difference between the following test methods:
这篇文章第一次发表已经快五年了,JavaScript 已经走过了漫长的道路。在重复原帖中的测试时,我发现以下测试方法之间没有一致的差异:
abc === undefinedabc === void 0typeof abc == 'undefined'typeof abc === 'undefined'
abc === undefinedabc === void 0typeof abc == 'undefined'typeof abc === 'undefined'
Even when I modified the tests to prevent Chrome from optimizing them away, the differences were insignificant. As such, I'd now recommend abc === undefinedfor clarity.
即使我修改了测试以防止 Chrome 优化它们,差异也微不足道。因此,abc === undefined为了清楚起见,我现在建议。
Relevant content from chrome://version:
相关内容来自chrome://version:
- Google Chrome: 67.0.3396.99 (Official Build) (64-bit) (cohort: Stable)
- Revision: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-heads/3396@{#790}
- OS: Windows
- JavaScript: V8 6.7.288.46
- User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
- 谷歌浏览器: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, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Original post 2013-11-01
原帖 2013-11-01
In Google Chrome, the following was ever so slightly faster than a typeoftest:
在谷歌浏览器中,以下比typeof测试稍微快一点:
if (abc === void 0) {
// Undefined
}
The difference was negligible. However, this code is more concise, and clearer at a glance to someone who knows what void 0means. Note, however, that abcmust still be declared.
差异可以忽略不计。但是,这段代码更简洁,对于知道什么void 0意思的人来说更清晰。但是请注意,abc仍然必须声明。
Both typeofand voidwere significantly faster than comparing directly against undefined. I used the following test format in the Chrome developer console:
双方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;
The results were as follows:
结果如下:
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
Note that the first row is in milliseconds, while the second row is in nanoseconds. A difference of 3.4 nanoseconds is nothing. The times were pretty consistent in subsequent tests.
请注意,第一行以毫秒为单位,而第二行以纳秒为单位。3.4 纳秒的差异不算什么。在随后的测试中,时间非常一致。
回答by Guffa
If it is undefined, it will not be equal to a string that contains the characters "undefined", as the string is not undefined.
如果未定义,它将不等于包含字符“未定义”的字符串,因为该字符串不是未定义的。
You can check the type of the variable:
您可以检查变量的类型:
if (typeof(something) != "undefined") ...
Sometimes you don't even have to check the type. If the value of the variable can't evaluate to false when it's set (for example if it's a function), then you can just evalue the variable. Example:
有时您甚至不必检查类型。如果变量的值在设置时无法评估为 false(例如,如果它是一个函数),那么您可以只评估该变量。例子:
if (something) {
something(param);
}
回答by Mathias Bynens
if (typeof foo == 'undefined') {
// Do something
};
Note that strict comparison (!==) is not necessary in this case, since typeofwill always return a string.
请注意,!==在这种情况下,严格比较 ( ) 不是必需的,因为typeof它将始终返回一个字符串。
回答by drzaus
Some scenarios illustrating the results of the various answers: http://jsfiddle.net/drzaus/UVjM4/
说明各种答案结果的一些场景:http: //jsfiddle.net/drzaus/UVjM4/
(Note that the use of varfor intests make a difference when in a scoped wrapper)
(请注意,在作用域包装器中使用varforin测试会有所不同)
Code for reference:
参考代码:
(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;
}
})();
And results:
结果:
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
回答by Marthijn
In this articleI read that frameworks like Underscore.jsuse this function:
在这篇文章中,我读到像Underscore.js这样的框架使用这个函数:
function isUndefined(obj){
return obj === void 0;
}
回答by Hrishi
Personally, I always use the following:
就个人而言,我总是使用以下方法:
var x;
if( x === undefined) {
//Do something here
}
else {
//Do something else here
}
The window.undefined property is non-writable in all modern browsers (JavaScript 1.8.5 or later). From Mozilla's documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, I see this: One reason to use typeof() is that it does not throw an error if the variable has not been defined.
window.undefined 属性在所有现代浏览器(JavaScript 1.8.5 或更高版本)中都是不可写的。从 Mozilla 的文档:https: //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined,我看到这一点:使用 typeof() 的一个原因是它不会抛出错误,如果变量尚未定义。
I prefer to have the approach of using
我更喜欢使用的方法
x === undefined
because it fails and blows up in my face rather than silently passing/failing if x has not been declared before. This alerts me that x is not declared. I believe all variables used in JavaScript should be declared.
因为如果之前没有声明 x,它会失败并在我面前爆炸,而不是默默地通过/失败。这提醒我 x 未声明。我相信 JavaScript 中使用的所有变量都应该声明。

