这个问题在这里已有答案:
- 检测未定义的对象属性 42个答案
- 如何在JavaScript中检查未定义的变量 13个答案
- 如何在javascript中处理'undefined'[重复] 3个答案
- 如何检查javascript中是否存在变量? 8个答案
起源
答案:
如果您想知道变量是否已被声明而不管其值如何,那么使用 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')
该 typeof 运算符保证返回一个字符串。直接比较 undefined 很麻烦 undefined 可以被覆盖。
window.undefined = "omg";
"omg" == undefined // true
正如@CMS指出的那样,这已经在ECMAScript第5版中修补了 undefined 是不可写的。
if (window.myVar) 还将包括这些虚假值,因此它不是很强大:
假 0 “” 为NaN 空值 未定义
感谢@CMS指出你的第三个案例 - if (myVariable) 也可以在两种情况下抛出错误。第一个是没有定义抛出a的变量 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"。我认为这是漫长的啰嗦和不必要的。 (我可以用更少的代码完成相同的工作。)
现在有些人在读到这篇文章时会痛苦地说话,尖叫道:“等等!等一下! 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 (和****咳嗽**** typeof)工作得很好。如果你真的在乎,你可以自己阅读这个主题。)
运用 typeof 是我的偏好。从未声明变量时它将起作用,与之不同的是 == 要么 === 运营商或类型强制使用 if。 (undefined不像 null,也可以在ECMAScript 3环境中重新定义,使其不可靠进行比较,尽管几乎所有常见环境现在都符合ECMAScript 5或更高版本)。
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
你需要使用 typeof 。
if (typeof something != "undefined") {
// ...
}
如果未定义,则它将不等于包含字符“undefined”的字符串,因为字符串未定义。
您可以检查变量的类型:
if (typeof(something) != "undefined") ...
有时您甚至不必检查类型。如果变量的值在设置时无法求值为false(例如,如果它是一个函数),那么您可以只评估变量。例:
if (something) {
something(param);
}
一些场景说明了各种答案的结果: http://jsfiddle.net/drzaus/UVjM4/
(注意使用 var 对于 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
if (typeof foo == 'undefined') {
// Do something
};
请注意严格比较(!==在这种情况下,没有必要,因为 typeof 将始终返回一个字符串。
在 本文 我读过像这样的框架 Underscore.js 使用此功能:
function isUndefined(obj){
return obj === void 0;
}
我知道检查的最可靠方式 undefined 是用 void 0。
这与新旧浏览器兼容,类似,并且不能被覆盖 window.undefined 在某些情况下可以。
if( myVar === void 0){
//yup it's undefined
}