变量===未定义与类型变量===“未定义”
jQuery 核心样式指南 建议两种不同的方法来检查变量是否被定义。
- 全局变量:
typeof variable === "undefined"
- 局部变量:
variable === undefined
- 属性:
object.prop === undefined
为什么jQuery 是否对全局变量使用一种方法,对局部变量和属性使用另一种方法?
The jQuery Core Style Guidelines suggest two different ways to check whether a variable is defined.
- Global Variables:
typeof variable === "undefined"
- Local Variables:
variable === undefined
- Properties:
object.prop === undefined
Why does jQuery use one approach for global variables and another for locals and properties?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
对于未声明的变量,
typeof foo
将返回字符串"undefined"
,而身份检查foo === undefined
将触发错误 “foo 未定义”。对于局部变量(您知道在某处声明的),不会发生此类错误,因此需要进行身份检查。
For undeclared variables,
typeof foo
will return the string"undefined"
, whereas the identity checkfoo === undefined
would trigger the error "foo is not defined".For local variables (which you know are declared somewhere), no such error would occur, hence the identity check.
我会坚持在任何地方使用
typeof foo === "undefined"
。那永远不会出错。我想 jQuery 推荐这两种不同方法的原因是它们在 jQuery 代码所在的函数中定义了自己的
undefined
变量,因此在该函数中undefined
是安全的来自外部的篡改。我还想象某个地方的某个人对两种不同的方法进行了基准测试,并发现 foo === undefined 更快,因此决定这是要走的路。 [更新:如评论中所述,与undefined
的比较也稍短,这可能是一个考虑因素。]但是,在实际情况下的增益将完全微不足道:此检查永远不会成为任何类型的瓶颈,并且您的损失是巨大的:评估主机对象的属性进行比较可能会引发错误,而typeof
检查永远不会。例如,在 IE 中使用以下内容来解析 XML:
安全地检查其是否具有
loadXML
方法:另一方面:
UPDATE
的另一个优点我忘记提及的 typeof
检查是它也适用于未声明的变量,而foo === undefined
检查则不然,实际上会抛出一个ReferenceError
。感谢@LinusKleen 提醒我。例如:底线:始终使用
typeof
检查。I'd stick to using
typeof foo === "undefined"
everywhere. 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 functionundefined
is safe from tampering from outside. I would also imagine that someone somewhere has benchmarked the two different approaches and discovered thatfoo === undefined
is faster and therefore decided it's the way to go. [UPDATE: as noted in the comments, the comparison withundefined
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 atypeof
check never will.For example, the following is used in IE for parsing XML:
To check whether it has a
loadXML
method safely:On the other hand:
UPDATE
Another advantage of the
typeof
check that I forgot to mention was that it also works with undeclared variables, which thefoo === undefined
check does not, and in fact throws aReferenceError
. Thanks to @LinusKleen for reminding me. For example:Bottom line: always use the
typeof
check.使用 typeof-variant 的另一个原因是:
undefined
可以被重新定义。typeof variable
的结果不能。更新:请注意,ES5 中的情况并非如此,全局
undefined
是一个不可配置、不可写的属性:但它仍然可以被局部变量
或参数隐藏:
Yet another reason for using the typeof-variant:
undefined
can be redefined.The result of
typeof variable
cannot.Update: note that this is not the case in ES5 there the global
undefined
is a non-configurable, non-writable property:But it still can be shadowed by a local variable:
or parameter:
对
variable === undefined
的性能提升感兴趣的人可以看一下这里,但这似乎只是 chrome 优化。Who is interested in the performance gain of
variable === undefined
, may take a look here, but it seems to be a chrome optimization only.因为
undefined
并不总是被声明,但是 jQuery 在它的 main 函数中声明了undefined
。因此,他们在内部使用安全的undefined
值,但在外部,他们使用typeof
样式来保证安全。Because
undefined
is not always declared, but jQuery declaresundefined
in its main function. So they use the safeundefined
value internally, but outside, they use thetypeof
style to be safe.对于局部变量,使用
localVar === undefined
检查将起作用,因为它们必须已在局部范围内的某个位置定义,否则它们将不会被视为局部变量。对于非本地且未在任何地方定义的变量,检查
someVar === undefined
将抛出异常:Uncaught ReferenceError: j is not Define这里有一些代码可以澄清我上面所说的。 请注意内嵌注释以进一步清晰。
如果我们像这样调用上面的代码:
输出将是这样的:
如果我们像这样调用上面的代码(实际上可以使用任何值):
输出将是:
当您像这样进行检查时:
typeof x == = 'undefined'
,您本质上是在问:请检查变量x
是否存在(已定义)在源代码中的某处。(更多或较少的)。如果您了解 C# 或 Java,则永远不会执行此类检查,因为如果它不存在,则不会编译。<== 摆弄我==>
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.For variables which are not local and not defined anywhere, the check
someVar === undefined
will throw exception: Uncaught ReferenceError: j is not definedHere is some code which will clarify what I am saying above. Please pay attention to inline comments for further clarity.
If we call the above code like this:
The output would be this:
If we call the above code like these (with any value actually):
The output will be:
When you do the check like this:
typeof x === 'undefined'
, you are essentially asking this: Please check if the variablex
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.<== Fiddle Me ==>
摘要:
在全局范围内,如果变量未声明或值为
undefined
,我们实际上希望返回 true:因为在全局范围内,我们不能 100% 确定是否声明了变量,这可能会给我们带来引用错误。当我们对未知变量使用
typeof
运算符时,如果未声明该变量,我们不会遇到此问题:这是因为,当变量未声明或当前持有值
undefined
时,typeof
运算符返回字符串undefined
,该值恰好是我们想要什么。undefined
Summary:
When at global scope we actually want to return true if the variable is not declared or has the value
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:This is due to the fact that the
typeof
operator returns the stringundefined
when a variable is not declared or currently hold the valueundefined
which is exactly what we want.undefined
jQuery 可能希望您在以后的函数中使用
let
和const
变量,而在 JavaScript 的 ES6 2015 设计中不允许您这样做使用任何本地作用域(函数)let
或const
变量,直到它们被声明。即使通过 Javascript 提升也不允许您对它们进行类型检查!如果您尝试这样做,JavaScript 会生成一个错误,这与
var
变量不同,后者在提升时会创建一个已声明但未初始化的变量,您可以键入 check 或 check 来查看其是否未定义。如果您在函数中声明了
let
或const
变量,但在尝试访问它之后,typeof
检查仍然会在 JavaScript 中产生引用错误!它的行为非常奇怪,对我来说,为什么要这样设计是不合逻辑的。但这就是为什么 jQuery 可能认为typeof
函数变量的使用没有用处。示例:上面的奇怪之处是,如何使用
typeof
无法检查不存在的局部变量的“未定义”,但函数中声明的let
变量却不能!所以这可能就是为什么我不会依赖 jQuery 来定义什么是最好的。 存在边缘情况。JavaScript 中“未定义”变量的更多怪异
**
undefined
有两种不同的表达式和三种不同的用途,如下:undefined
时也是如此变量直到被赋值。因此,在这种情况下检查“typeof”可以防止出现此错误,如下所示:JavaScript 中访问但未声明的所有对象和类型都将默认为“未定义”类型。因此,这里的教训是首先尝试检查
typeof
,以防止丢失变量错误!undefined
原始值:所有尚未赋值的声明变量在 JavaScript 中都被赋予undefined
的 primitve。如果您已声明变量,但尚未初始化它,则会为其分配默认的原始类型未定义
。这与“未定义”类型不同。undefined
的原始值是一个保留值,但可以更改,但这不是这里所要求的。请注意,这仅捕获所有已声明但未初始化的变量:未定义
基元:最后,对象属性的行为与 JavaScript 中的变量不同。对象属性在丢失时不会变成未定义类型,而是简单地为未声明的变量分配原语undefined
。所以它们的行为就像#2:最佳实践
最后......这是始终检查“未定义”类型和
未定义
原始值的一个非常好的理由所有 JavaScript 代码中的变量。大多数人会说,你很少需要两者。可能有一天,在不存在的库中访问丢失的变量并创建令人讨厌的 JavaScript 引用错误!因此,我总是按照以下顺序执行此检查,以阻止 JavaScript 中的所有错误:jQuery probably expects you to be using
let
andconst
variables in functions going forward, which in JavaScript's ES6 2015 design do NOT allow you to use any local scope (function)let
orconst
variables until they are declared. Even hoisting by Javascript does not allow you to even type-check them!If you try and do that, JavaScript generates an error, unlike with
var
variables which when hoisted creates a declared but uninitialized variable you can type check or check to see if its undefined.If you declare a
let
orconst
variable in a function, but AFTER trying to access it,typeof
checks still create a Reference Error in JavaScript! Its very odd behavior, and illogical to me why it was designed that way. But that is why jQuery likely sees no use fortypeof
function variable use. Example:It is odd above how a non-existing local variable cant be checked using
typeof
for 'undefined', but a declaredlet
variable in the function cannot! So this is likely why I would not depend on jQuery to define what is best. There are edge cases.More Weirdness on "undefined" variables in JavaScript
**
undefined
has two different expressions, and three different uses, as follows:undefined
which is assigned to declared variables until assigned a value. So checking the "typeof" prevents this error in this one case as follows:All objects and types in JavaScript that are accessed but not declared will default to a type of "undefined". So, the lesson here is try and check for the
typeof
first, to prevent missing variable errors!undefined
primitive values : All declared variables not yet assigned a value are assigned in JavaScript the primitve ofundefined
. If you have declared a variable, but not initialized it yet, its assigned this default primitive type ofundefined
. That is not same as an "undefined" type. The primitive value ofundefined
is a reserved value but can be altered, but that's not what is asked here. Notice this catches all declared but uninitialized variables only:undefined
primitives : Lastly, Object properties do NOT behave like variables in JavaScript. Object properties, when missing do not become undefined types, but are simply assigned the primitiveundefined
as above for undeclared variables. So they act like #2:BEST PRACTICE
Lastly....this is a VERY GOOD REASON to always check for BOTH the "undefined" type and the
undefined
primitive value on variables in all your JavaScript code. Most will say, you will rarely need both. There may come a day when a missing variable is accessed in a library that does not exist and creates a nasty JavaScript REFERENCE ERROR! So I always do this check, and in this order, to stop all errors in JavaScript:在节点 v6.9.1 上,
typeof a === 'undefined'
比a === 'undefined'
快大约 2 倍。typeof a === 'undefined'
is faster thena === 'undefined'
by about 2 times on node v6.9.1.