这个问题在这里已经有了答案:Detecting an undefined object property (50 answers) How to check a not-defined variable in JavaScript (15 answers) How to handle 'undefined' in JavaScript [duplicate] (3 answers) How can I check if JavaScript 中是否存在变量? (8 个回答) 7 年前关闭。
测试 JavaScript 中是否未定义变量的最合适方法是什么?
我见过几种可能的方法:
if (window.myVariable)
或者
if (typeof(myVariable) != "undefined")
或者
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
undefined
,还是同时检查null
?
如果您有兴趣了解变量是否已被声明而不管其值如何,那么使用 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')
与 undefined
的直接比较很麻烦,因为 undefined
可能会被覆盖。
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?
}
我个人使用
myVar === undefined
警告:请注意 ===
用于 ==
并且 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
)工作得很好。如果你真的在乎,你可以自己阅读有关此主题的内容。)
undefined
的可能性稍大一些,因为人们确实将它用于此类检查。有些人在进行此类检查时习惯性地将常数放在左侧:if (undefined == someVariable)
。只需一个错字就可以静默地重新定义 undefined
:if (undefined = someVariable)
。
undefined
的代码。即使我这样做了,我使用 ===
而不是 ==
的事实也使得错字极不可能出现。但 ==
不正确的事实更令人担忧。无论如何,这样的错误通常很容易找到。有点像这个错误:typeof x == "undefned"
。
myVar
确实未定义,则代码将抛出错误,并且很容易测试 - jsfiddle.net/WcM5g 正确的方法是 typeof myVar === 'undefined'
。
var
关键字或函数参数。在我(故意)编写尝试以任何方式对未声明的变量进行操作的代码之前,我会出卖自己的灵魂。请记住,未声明和未定义是 JS 中的两个不同概念。
if (NULL = myVar)
无法编译并立即被捕获,而 if (myVar = NULL)
会产生一个可能难以追踪的错误,具体取决于它周围的其他代码。现代编译器应该给你一个警告,但是许多有经验的 C 程序员已经养成了交换顺序的习惯。
2020 更新
我更喜欢 typeof
检查(即 undefined
可以重新定义)的原因之一与 ECMAScript 5 的大规模采用无关。另一个,您可以使用 typeof
检查未声明变量的类型,总是小众。因此,我现在建议在大多数情况下使用直接比较:
myVariable === undefined
2010年的原始答案
使用 typeof
是我的偏好。当变量从未被声明时,它将起作用,这与与 ==
或 ===
运算符的任何比较或使用 if
的类型强制不同。 (与 null
不同,undefined
也可能在 ECMAScript 3 环境中重新定义,这使得比较不可靠,尽管现在几乎所有常见的环境都与 ECMAScript 5 或更高版本兼容)。
if (typeof someUndeclaredVariable == "undefined") {
// Works
}
if (someUndeclaredVariable === undefined) {
// Throws an error
}
'xyz' in window
是比 typeof xyz == "undefined"
更好的答案,因为它正在测试错误的东西。 in
运算符检查属性是否存在,而不管其值如何,而问题至少似乎是在询问如何测试变量的值是否为 undefined
。 var foo; "foo" in window
可能是我选择的一个更好的例子;这返回 true 而 foo
肯定是未定义的。
xyz === undefined
比 typeof xyz == "undefined"
好?同意全局变量,但我们两个中只有您一直建议检查 window
的属性。
您可以使用 typeof
,如下所示:
if (typeof something != "undefined") {
// ...
}
something !== undefined
,假设您已经谨慎地完成了 var undefined
。
typeof
。
typeof
是最安全且不易出错的选项。除了写这样令人困惑的评论之外,我还会编辑答案以使用另一个术语而不是 need。比如 “你可以|应该|更好|可能使用 typeof
” :)
2018-07-25 更新
这篇文章第一次发表已经将近五年了,JavaScript 已经走过了漫长的道路。在重复原始帖子中的测试时,我发现以下测试方法之间没有一致的区别:
abc === 未定义
abc === 无效 0
typeof abc == '未定义'
typeof abc === '未定义'
即使我修改了测试以防止 Chrome 优化它们,但差异并不显着。因此,为了清楚起见,我现在推荐 abc === undefined
。
chrome://version
的相关内容:
Google Chrome: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
原帖 2013-11-01
在 Google Chrome 中,以下测试比 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 纳秒的差异不算什么。在随后的测试中,时间非常一致。
===
来测试 undefined
!
void 0
对我来说听起来更不寻常,2) 你应该改为 share your perf tests ,但主要是 3) 如果 abc
未定义,您的第一个示例 (abc === void 0
) 将引发异常。
typeof
测试。
如果它是未定义的,它将不等于包含字符“未定义”的字符串,因为该字符串不是未定义的。
您可以检查变量的类型:
if (typeof(something) != "undefined") ...
有时您甚至不必检查类型。如果变量的值在设置时不能评估为 false(例如,如果它是一个函数),那么您可以只评估变量。例子:
if (something) {
something(param);
}
typeof
是运算符,而不是函数。
if (typeof foo == 'undefined') {
// Do something
};
请注意,在这种情况下不需要严格比较 (!==
),因为 typeof
将始终返回一个字符串。
};
) 是什么?
;
就无法处理 if(){}
的缩小器……您指的是哪些缩小器?你说这就是你结束所有其他陈述的方式......我想这是真的。但是,块语句 {}
已经是它自己的语句。从技术上讲,添加 ;
使其成为两个语句。从语法上讲,它是多余的。即使是自动分号插入也不会在那里添加分号......
function() {}
声明之后使用分号。你是对的——显然在 if
语句之后不需要它,但不知何故我仍然认为它是有道理的。
说明各种答案结果的一些场景: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
undefined
;这不仅可以防止“哦,但是 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
:(function($, undefined){ /* undefined is 'abc' in here */ })(jQuery, 'abc');
,这就是为什么 ppl 抱怨它在技术上不安全,除非您 100% 确定您知道代码在哪里运行。
我知道检查 undefined
的最可靠方法是使用 void 0
。
这与新旧浏览器兼容,并且在某些情况下不能像 window.undefined
那样被覆盖。
if( myVar === void 0){
//yup it's undefined
}
undefined !== void 0
,您可能在所述代码库中遇到其他严重问题。
myVar
之前未声明时,它会引发抛出错误。
由于其他答案都没有帮助我,我建议这样做。它在 Internet Explorer 8 中对我有用:
if (typeof variable_name.value === 'undefined') {
// variable_name is undefined
}
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
// These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}
与@Thomas Eding 答案相反:
如果我忘记在我的代码中声明 myVar
,那么我会得到 myVar is not defined
。
让我们举一个真实的例子:
我有一个变量名,但我不确定它是否在某处声明。
那么@Anurag 的回答会有所帮助:
var myVariableToCheck = 'myVar';
if (window[myVariableToCheck] === undefined)
console.log("Not declared or declared, but undefined.");
// Or you can check it directly
if (window['myVar'] === undefined)
console.log("Not declared or declared, but undefined.");
myVar is not defined
错误将是一件好 的事情,尤其是当您专门编写“如果我忘记 声明”[强调我的] 时。当我在代码运行之前遇到错误时,我喜欢它。如果您想了解我对您的回答的更多看法,我已经在我的回答下发表了相关评论。
var x;
if (x === undefined) {
alert ("I am declared, but not defined.")
};
if (typeof y === "undefined") {
alert ("I am not even declared.")
};
/* One more thing to understand: typeof ==='undefined' also checks
for if a variable is declared, but no value is assigned. In other
words, the variable is declared, but not defined. */
// Will repeat above logic of x for typeof === 'undefined'
if (x === undefined) {
alert ("I am declared, but not defined.")
};
/* So typeof === 'undefined' works for both, but x === undefined
only works for a variable which is at least declared. */
/* Say if I try using typeof === undefined (not in quotes) for
a variable which is not even declared, we will get run a
time error. */
if (z === undefined) {
alert ("I am neither declared nor defined.")
};
// I got this error for z ReferenceError: z is not defined
我将它用作函数参数并在函数执行时将其排除在外,这样我就得到了“真正的”未定义。尽管它确实需要您将代码放入函数中。我在阅读 jQuery 源代码时发现了这一点。
undefined = 2;
(function (undefined) {
console.log(undefined); // prints out undefined
// and for comparison:
if (undeclaredvar === undefined) console.log("it works!")
})()
当然,您可以只使用 typeof
。但无论如何,我所有的代码通常都在一个包含函数中,所以使用这种方法可能会在这里和那里为我节省一些字节。
var undeclaredvar = window.someUndeclaredVar; if (undeclaredvar === undefined) console.log("it works!").
请在发布之前测试您的示例。
不定期副业成功案例分享
myVariable
未声明,第三种情况将抛出ReferenceError
...undefined
现在被描述为不可写、不可配置和不可枚举。因此,window.undefined = "omg";
将简单地以静默方式失败或在严格模式下抛出。undefined
在现代浏览器中是不可变的。设置window.undefined
什么都不做。