jQuery Core Style Guidelines提出了两种不同的方法来检查变量是否已定义。
typeof variable === "undefined"
variable === undefined
object.prop === undefined
为什么jQuery对全局变量使用一种方法而对本地和属性使用另一种方法?
答案 0 :(得分:327)
对于未声明的变量,typeof foo
将返回字符串文字"undefined"
,而身份检查foo === undefined
将触发错误“foo未定义”。
对于局部变量(你知道在某处声明),不会发生这样的错误,因此进行身份检查。
答案 1 :(得分:110)
我坚持在任何地方使用typeof foo === "undefined"
。这永远不会出错。
我认为jQuery推荐两种不同方法的原因是它们在jQuery代码所在的函数中定义了自己的undefined
变量,因此在该函数中undefined
可以安全地从外部篡改。我还想象某个地方有人对这两种不同的方法进行了基准测试,并发现foo === undefined
更快,因此决定了它的出路。 [更新:如评论中所述,与undefined
的比较也略短,这可能是一个考虑因素。] 但是,实际情况下的收益将是微不足道的:此检查永远不会出现任何瓶颈,你失去的是重要的:评估一个主机对象的属性进行比较会引发错误,而typeof
检查永远不会。
例如,IE中使用以下内容来解析XML:
var x = new ActiveXObject("Microsoft.XMLDOM");
要安全地检查它是否有loadXML
方法:
typeof x.loadXML === "undefined"; // Returns false
另一方面:
x.loadXML === undefined; // Throws an error
<强>更新强>
我忘了提及的typeof
检查的另一个优点是它也适用于未声明的变量,foo === undefined
检查没有,实际上会抛出ReferenceError
。感谢@LinusKleen提醒我。例如:
typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError
底线:始终使用typeof
检查。
答案 2 :(得分:26)
使用typeof-variant的另一个原因:undefined
可以重新定义。
undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
typeof variable
的结果不能。
更新:请注意,这不是ES5中的情况。
答案 3 :(得分:6)
因为并不总是声明undefined
,但是jQuery在其main函数中声明了undefined
。因此,他们在内部使用安全的undefined
值,但在外部,他们使用typeof
样式是安全的。
答案 4 :(得分:6)
谁对variable === undefined
的性能提升感兴趣,可以看看这里,但它似乎只是镀铬优化。
答案 5 :(得分:1)
对于局部变量,使用localVar === undefined
进行检查是有效的,因为它们必须已在本地范围内的某处定义,或者它们不会被视为本地变量。
对于非本地且未在任何地方定义的变量,检查someVar === undefined
将抛出异常:未捕获的ReferenceError:j未定义
以下是一些代码,它将阐明我上面所说的内容。 请注意内联评论以进一步明确。
function f (x) {
if (x === undefined) console.log('x is undefined [x === undefined].');
else console.log('x is not undefined [x === undefined.]');
if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
else console.log('x is not undefined [typeof(x) === \'undefined\'].');
// This will throw exception because what the hell is j? It is nowhere to be found.
try
{
if (j === undefined) console.log('j is undefined [j === undefined].');
else console.log('j is not undefined [j === undefined].');
}
catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}
// However this will not throw exception
if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};
如果我们这样调用上面的代码:
f();
输出将是:
x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
如果我们像这样调用上面的代码(实际上有任何值):
f(null);
f(1);
输出将是:
x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
当您执行以下检查:typeof x === 'undefined'
时,您实际上是在问这个:请检查源代码中某处是否存在变量x
(已定义)。(或多或少)。如果您了解C#或Java,则永远不会执行此类检查,因为如果它不存在,则无法编译。
答案 6 :(得分:1)
在全局范围内,如果变量未声明或值为undefined
,我们实际上想返回true:
var globalVar1;
// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);
// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);
因为在全局范围内,我们不确定100%是否声明了变量,否则可能会给我们带来referenceError。当我们在未知变量上使用typeof
运算符时,未声明该变量时不会出现此问题:
var globalVar1;
console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');
这是由于以下事实:typeof
运算符在未声明变量或当前持有值undefined
时返回字符串undefined
,而这正是我们想要的。
undefined
var obj = {};
console.log(obj.myProp === undefined);
答案 7 :(得分:-1)
typeof a === 'undefined'
比a === 'undefined'
快2倍。