[英]variable === undefined vs. typeof variable === "undefined"
The jQuery Core Style Guidelines suggest two different ways to check whether a variable is defined. jQuery Core Style Guidelines提出了两种不同的方法来检查是否定义了变量。
typeof variable === "undefined"
全局变量: typeof variable === "undefined"
variable === undefined
局部变量: variable === undefined
object.prop === undefined
属性: object.prop === undefined
Why does jQuery use one approach for global variables and another for locals and properties?为什么 jQuery 对全局变量使用一种方法而对局部变量和属性使用另一种方法?
For undeclared variables, typeof foo
will return the string literal "undefined"
, whereas the identity check foo === undefined
would trigger the error "foo is not defined" .对于未声明的变量, typeof foo
将返回字符串文字"undefined"
,而身份检查foo === undefined
将触发错误"foo is not defined" 。
For local variables (which you know are declared somewhere), no such error would occur, hence the identity check.对于局部变量(您知道在某处声明),不会发生此类错误,因此需要进行身份检查。
I'd stick to using typeof foo === "undefined"
everywhere.我会坚持在任何地方使用typeof foo === "undefined"
。 That can never go wrong.那永远不会出错。
I imagine the reason why jQuery recommends the two different methods is that they define their own undefined
variable within the function that jQuery code lives in, so within that function undefined
is safe from tampering from outside.我想 jQuery 推荐这两种不同方法的原因是它们在 jQuery 代码所在的函数中定义了自己的undefined
变量,因此在该函数中undefined
可以防止外部篡改。 I would also imagine that someone somewhere has benchmarked the two different approaches and discovered that foo === undefined
is faster and therefore decided it's the way to go.我还想象某个地方有人对两种不同的方法进行了基准测试,发现foo === undefined
更快,因此决定这是要走的路。 [UPDATE: as noted in the comments, the comparison with undefined
is also slightly shorter, which could be a consideration.] However, the gain in practical situations will be utterly insignificant: this check will never, ever be any kind of bottleneck, and what you lose is significant: evaluating a property of a host object for comparison can throw an error whereas a typeof
check never will. [更新:如评论中所述,与undefined
的比较也略短,这可能是一个考虑因素。]然而,实际情况中的收益将完全微不足道:此检查永远不会成为任何类型的瓶颈,并且你失去的东西很重要:评估主机对象的属性进行比较可能会引发错误,而typeof
检查永远不会。
For example, the following is used in IE for parsing XML:例如,在 IE 中使用以下内容来解析 XML:
var x = new ActiveXObject("Microsoft.XMLDOM");
To check whether it has a loadXML
method safely:要安全地检查它是否具有loadXML
方法:
typeof x.loadXML === "undefined"; // Returns false
On the other hand:另一方面:
x.loadXML === undefined; // Throws an error
UPDATE更新
Another advantage of the typeof
check that I forgot to mention was that it also works with undeclared variables, which the foo === undefined
check does not, and in fact throws a ReferenceError
.我忘记提及的typeof
检查的另一个优点是它也适用于未声明的变量,而foo === undefined
检查则不然,实际上会抛出一个ReferenceError
。 Thanks to @LinusKleen for reminding me.感谢@LinusKleen 提醒我。 For example:例如:
typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError
Bottom line: always use the typeof
check.底线:始终使用typeof
检查。
Yet another reason for using the typeof-variant: undefined
can be redefined.使用 typeof-variant 的另一个原因: undefined
可以重新定义。
undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
The result of typeof variable
cannot. typeof variable
的结果不能。
Update : note that this is not the case in ES5 there the global undefined
is a non-configurable, non-writable property:更新:请注意,在 ES5 中情况并非如此,全局undefined
是一个不可配置、不可写的属性:
15.1.1 Value Properties of the Global Object 15.1.1 全局对象的值属性
[...] [...]
15.1.1.3 undefined 15.1.1.3 未定义
The value ofundefined
is undefined (see 8.1).undefined
值为 undefined(见 8.1)。 This property has the attributes该属性具有以下属性
{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。
But it still can be shadowed by a local variable:但它仍然可以被局部变量遮蔽:
(function() {
var undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
})()
or parameter:或参数:
(function(undefined) {
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
})("foo")
Because undefined
is not always declared, but jQuery declares undefined
in its main function.因为undefined
并不总是被声明的,但是 jQuery 在它的 main 函数中声明了undefined
。 So they use the safe undefined
value internally, but outside, they use the typeof
style to be safe.所以他们在内部使用安全的undefined
值,但在外部,他们使用typeof
样式是安全的。
Who is interested in the performance gain of variable === undefined
, may take a look here, but it seems to be a chrome optimization only.谁对variable === undefined
的性能增益感兴趣,可以看看这里,但它似乎只是一个 chrome 优化。
For local variables, checking with localVar === undefined
will work because they must have been defined somewhere within the local scope or they will not be considered local.对于局部变量,使用localVar === undefined
检查会起作用,因为它们必须在局部作用域内的某处定义,否则它们将不被视为局部变量。
For variables which are not local and not defined anywhere, the check someVar === undefined
will throw exception: Uncaught ReferenceError: j is not defined对于非本地且未在任何地方定义的变量,检查someVar === undefined
将抛出异常: Uncaught ReferenceError: j is not defined
Here is some code which will clarify what I am saying above.这里有一些代码可以澄清我上面所说的内容。 Please pay attention to inline comments for further clarity .请注意内嵌注释以进一步明确。
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\'].');
};
If we call the above code like this:如果我们这样调用上面的代码:
f();
The output would be this:输出将是这样的:
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.
If we call the above code like these (with any value actually):如果我们像这样调用上面的代码(实际上是任何值):
f(null);
f(1);
The output will be:输出将是:
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.
When you do the check like this: typeof x === 'undefined'
, you are essentially asking this: Please check if the variable x
exists (has been defined) somewhere in the source code.当您像这样进行检查时: typeof x === 'undefined'
,您实际上是在问这个问题:请检查变量x
存在(已定义)源代码中的某处。 (more or less). (或多或少)。 If you know C# or Java, this type of check is never done because if it does not exist, it will not compile.如果您了解 C# 或 Java,则永远不会进行此类检查,因为如果它不存在,则不会编译。
When at global scope we actually want to return true if the variable is not declared or has the value undefined
:在全局范围内,如果变量未声明或值为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);
Because in global scope we are not 100% sure if a variable is declared this might give us a referenceError.因为在全局范围内,我们不能 100% 确定是否声明了一个变量,这可能会给我们一个引用错误。 When we use the typeof
operator on the unknown variable we are not getting this issue when the variable is not declared:当我们在未知变量上使用typeof
运算符时,我们不会在未声明变量时遇到此问题:
var globalVar1; console.log(typeof globalVar1 === 'undefined'); console.log(typeof globalVar2 === 'undefined');
This is due to the fact that the typeof
operator returns the string undefined
when a variable is not declared or currently hold the value undefined
which is exactly what we want.这是因为typeof
运算符在未声明变量或当前保存的值undefined
时返回undefined
字符串,这正是我们想要的。
undefined
对于对象属性,我们没有这个问题,因为当我们尝试查找一个不存在的对象属性时,我们也会得到值undefined
var obj = {}; console.log(obj.myProp === undefined);
typeof a === 'undefined'
更快然后a === 'undefined'
由节点v6.9.1约2倍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.