Javascript 变量 === 未定义与 typeof 变量 === “未定义”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4725603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
variable === undefined vs. typeof variable === "undefined"
提问by Patrick McElhaney
The jQuery Core Style Guidelinessuggest two different ways to check whether a variable is defined.
在jQuery的核心风格指南建议两种不同的方法来检查一个变量是否被定义。
- Global Variables:
typeof variable === "undefined"
- Local Variables:
variable === undefined
- Properties:
object.prop === undefined
- 全局变量:
typeof variable === "undefined"
- 局部变量:
variable === undefined
- 特性:
object.prop === undefined
Why does jQuery use one approach for global variables and another for locals and properties?
为什么 jQuery 对全局变量使用一种方法而对局部变量和属性使用另一种方法?
回答by Linus Kleen
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 knoware declared somewhere), no such error would occur, hence the identity check.
对于局部变量(您知道在某处声明),不会发生此类错误,因此需要进行身份检查。
回答by Tim Down
I'd stick to using typeof foo === "undefined"
everywhere. That can never go wrong.
我会坚持在typeof foo === "undefined"
任何地方使用。那永远不会出错。
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. 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. [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.
我想 jQuery 推荐这两种不同方法的原因是它们undefined
在 jQuery 代码所在的函数中定义了自己的变量,因此在该函数中undefined
是安全的,不会被外部篡改。我还想像某个地方的某个人对这两种不同的方法进行了基准测试,发现它foo === undefined
更快,因此决定这是要走的路。[更新:如评论中所述,与 的比较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
. Thanks to @LinusKleen for reminding me. For example:
typeof
我忘记提及的检查的另一个优点是它也适用于未声明的变量,foo === undefined
检查不这样做,并且实际上抛出一个ReferenceError
. 感谢@LinusKleen 提醒我。例如:
typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError
Bottom line: always use the typeof
check.
底线:始终使用typeof
支票。
回答by Jakob
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.3 undefined
The value ofundefined
is undefined (see 8.1). This property has the attributes
{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
15.1.1 全局对象的值属性
[...]
15.1.1.3 undefined
的值undefined
未定义(见 8.1)。此属性具有属性
{ [[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")
回答by Struppi
Because undefined
is not always declared, but jQuery declares undefined
in its main function. So they use the safe undefined
value internally, but outside, they use the typeof
style to be safe.
因为undefined
并不总是声明的,但 jQueryundefined
在其 main 函数中声明。所以他们在undefined
内部使用安全值,但在外部,他们使用typeof
样式是安全的。
回答by RiZKiT
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 优化。
回答by CodingYoshi
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.
对于局部变量,检查 withlocalVar === 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.(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.
当您像这样进行检查时:typeof x === 'undefined'
,您实际上是在问:请检查x
源代码中某处是否存在(已定义)变量。(或多或少)。如果您了解 C# 或 Java,则永远不会进行此类检查,因为如果它不存在,则不会编译。
回答by Willem van der Veen
Summary:
概括:
When at global scope we actually want to return true if the variable is not declared or has the value undefined
:
在全局范围内,如果变量未声明或具有值,我们实际上希望返回 true undefined
:
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. When we use the typeof
operator on the unknown variable we are not getting this issue when the variable is not declared:
因为在全局范围内,我们不能 100% 确定是否声明了一个变量,这可能会给我们一个引用错误。当我们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
- With local variables we don't have this problem because we know beforehand that this variable will exist. We can simply look in the respective function if the variable is present.
- With object properties we don't have this problem because when we try to lookup an object property which does not exist we also get the value
undefined
- 对于局部变量,我们没有这个问题,因为我们事先知道这个变量会存在。如果变量存在,我们可以简单地查看相应的函数。
- 对于对象属性,我们没有这个问题,因为当我们尝试查找不存在的对象属性时,我们也会得到值
undefined
var obj = {};
console.log(obj.myProp === undefined);
回答by Eduard Popov
typeof a === 'undefined'
is faster then a === 'undefined'
by about 2 times on node v6.9.1.
typeof a === 'undefined'
a === 'undefined'
在节点 v6.9.1 上快了大约 2 倍。