如果JavaScript中未定义变量,最合适的测试方法是什么?
我见过几种可能的方法:
if (window.myVariable)
Or
if (typeof(myVariable) != "undefined")
Or
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
如果JavaScript中未定义变量,最合适的测试方法是什么?
我见过几种可能的方法:
if (window.myVariable)
Or
if (typeof(myVariable) != "undefined")
Or
if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
当前回答
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
// These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}
其他回答
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
// These statements execute.
}
if (x === undefined) { // Throws a ReferenceError
}
如果您有兴趣了解变量是否已声明,而不管其值如何,那么使用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
如果您想知道变量是否尚未声明或值未定义,请使用typeof运算符,它保证返回字符串:
if (typeof myVar !== 'undefined')
与undefined的直接比较很麻烦,因为undefineed可以被覆盖。
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?
}
我使用它作为函数参数,并在函数执行时排除它,这样我就得到了未定义的“真实”。尽管它确实需要您将代码放在函数中。我在阅读jQuery源代码时发现了这一点。
undefined = 2;
(function (undefined) {
console.log(undefined); // prints out undefined
// and for comparison:
if (undeclaredvar === undefined) console.log("it works!")
})()
当然,你可以使用typeof。但无论如何,我的所有代码通常都在一个包含函数中,所以使用这个方法可能会在这里和那里节省一些字节。
说明各种答案结果的一些场景:http://jsfiddle.net/drzaus/UVjM4/
(请注意,在测试中使用var会在作用域包装器中产生差异)
参考代码:
(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
与@Thomas Eding的回答相反:
如果我忘记在代码中声明myVar,那么我将得到myVar未定义。
让我们举一个真实的例子:
我有一个变量名,但我不确定它是否在某处声明。
那么@Anurak的回答会有所帮助:
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.");