Why does one reuse `undefined`?
在John Resig关于他如何构建jQuery 1.4的幻灯片中,他提到了一个点,他在jQuery闭包中添加了一个undefined变量,因为"我们可以重用(变量)"。
undefined不是普通变量:
1 2 3 4
| > var undefined = 4
undefined
> undefined
undefined |
因此,我们知道undefined不是变量。 那么为什么在jQuery源代码中重新定义undefined呢?
-
在旧浏览器中,可以重新定义全局undefined。 情况已经不是这样了。
-
@CrazyTrain这应该是一个答案。
-
@CrazyTrain是对的,你可以在一个闭包中定义undefined :( function(undefined){undefined = 5; console.log(undefined);})()
因为在某些JavaScript引擎中,可以将undefined设置为一个值。 这是为了确保undefined真的是undefined。
-
我建议不要那样保护。这只是愚蠢的。如果人们愚蠢到重新定义undefined,他们应该得到什么。
-
@ user1737909:足够公平,但如果它是恶意脚本怎么办:O
-
@ user1737909存在涉及来自多个来源的脚本的上下文(想想"杂志"广告支持的网站),因此人们可能希望保护自己的代码免受其他人的愚蠢(或恶意)。
-
无所谓。如果有人重新定义prototype怎么办?你将以同样的方式注定,并且你无法防范一切。只是防止未定义的意志最多让你感觉更安全。
-
@ user1737909虽然我同意,但我认为你不能构建一个javascript库,也不会添加一些故障保险箱来防止意外错误,不管它们多么愚蠢。
-
是的,在jQuery的情况下,对于minifiers来说它可能更好(即使你应该gzip)。我只是添加一个通用说明,因为我认为我们大多数人都不会处理jQuery必须处理的问题。 (然后我们谈论null,"是一个javascript值a Maybe Maybe T?";等)
-
值得一提。可以设置undefined的JS引擎不符合ES5规范。
-
@BenjaminGruenbaum:这只是旧浏览器,这是一个值得关注的问题。请记住,ES5直到2009年12月才发布;唯一可以分配给undefined的浏览器是在ES5存在之前发布的。
除了+ Rocket Hazmat的答案之外,当您的代码经常使用undefined时,您可以在压缩后稍微减小文件大小。 那是因为局部变量undefined的名称可能被压缩器损坏,而全局undefined可能不会:
1 2 3 4 5 6 7 8
| foo === undefined;
// ^----- don't touch this, put"undefined" in the compressed result
(function (undefined) {
foo === undefined;
})();
// may however be mangled to
(function(u){foo===u})(); |
-
或使用void 0:p。
-
@ user1737909:void 0不能从6个字符减少。 undefined可以减少到1。
-
你在谈论gzip压缩还是缩小?
-
@Ian:缩小。
-
@ josh3736那么我希望minifier不会触及undefined,因为它应该知道它在技术上是一个保留字。在这种情况下,void 0更短。 gzipping它可能会产生你正在谈论的效果
-
我不知道undefined作为参数是否比void 0快。可能没关系。 (function (u) { })()是1字符串undefined,我想知道JIT是否能够静态优化它(可能)
-
@Ian局部变量名称缩小有什么问题?
-
@roasted我认为我没有意识到我们正在讨论局部变量undefined而不是全局保留undefined。我想我没有正确阅读这个答案。只要undefined是局部变量,那么josh3736是正确的,它可以正确缩小
-
@Ian:是的undefined只是严格模式下的保留字。在普通的JS中,它是完全正常的(在旧引擎中)或不可写的变量(在新引擎中)。
-
@ josh3736这与严格模式或引擎无关。你在谈论缩小。我的观点是,缩小器不会缩小undefined,因为它应该知道它是一个全局保留字。我没有考虑在本地重新声明它(无论是作为参数还是用var),在这种情况下,缩小器不应该对它进行相同处理并且应该正确地缩小它。我在质疑你时错了,但这只是因为你在谈论一个本地undefined变量(不是全局变量)
-
@Ian:我所说的是,除非你选择了严格模式,否则全局undefined(它不是"保留字")绝对没有什么特别之处。这是一个完全迂腐的观点,你是对的,通常一个缩小器通常不会触及全局变量。
-
@ josh3736您可以随意调用它(或不调用它),但它是一个"保留字",因为它是该语言的一个特性,不应该被修改。通过"一个缩小器通常不会触及全局变量",我希望你的意思是他们没有。如果minifier缩小了全局变量,则不应使用它。是的,从ES5开始,全局undefined有一些特别之处,而不是严格的模式...它是不可写的:es5.github.io/#x15.1.1.3
-
@Ian,我专门考虑了Closure Compiler的高级优化选项,它在启用时重命名全局变量。关于undefined,请记住ES5直到2009年12月才发布。在ES3 /旧浏览器中,undefined没有什么特别之处。在ES5中,全局对象的属性undefined是只读的,但仍然不会使它成为保留字。同样,这完全是迂腐的,但undefined未指定为保留字。
-
@ josh3736关于Closure Compiler的好点 - 没有意识到它有一个选项来重命名全局变量而不是自动总是这样做。对不起,我没有说清楚,我明白这不是一个保留的词,这就是我用"包围它的原因。我想一个更好的描述符会像你提到的那样"只读"。而且你显然对于ES5之前没有将undefined定义为只读是正确的,但我的另一点是目标是ES5,而不是严格模式。而且这不是迂腐的;我宁愿我和其他人理解正确的事情,所以我喜欢像我们一样充实它