Semicolon before self-invoking function?
在JavaScript中使用自调用函数之前使用分号有什么好处。 我在几个流行的jQuery插件中看到了这种方法,我很想知道这是否是我不知道的JavaScript中的下一个很棒的东西。 先谢谢你们!
-
代码示例? 我很好奇。
-
分号位于左侧paren (的前面,以防止JavaScript解释器将parens解释为函数调用操作符。
-
@xantos例如fancybox:github.com/vanntastic/fancy-box/blob/master/jquery.fancybox/…
-
粉碎杂志文章使用这个jquery插件boilterplate:coding.smashingmagazine.com/2011/10/11/…
-
@ZachL。 我真的很喜欢这篇文章。 谢谢!
如果将两个文件与自调用函数连接在一起,如下所示:
文件A:
档案B:
文件A + B:
1
| (function(){...A...})()(function(){...B...})() |
你有两个没有分隔符的语句。当您将文件合并在一起然后缩小它们时会发生这种情况。
现在,文件B的作者在前面加了一个分号:
档案B2:
1
| ;(function(){...B2...})() |
你会得到一个有效的脚本:
1
| (function(){...A...})();(function(){...B2...})() |
-
那么,为什么我更喜欢在自我调用函数面前而不是在它之后使用分号?
-
@ 7elephant 2分号不会伤害,但没有分号,所以这是一个安全问题,尤其适用于大型项目
-
预防医学
-
如果前一个语句没有以一个语句结尾,您是否还在每个语句的开头包含分号?
-
@Brandon不,只在整个文件的前面。无论如何,连接文件中的语句应该用分号分隔,以创建有效的JavaScript代码。
自调用函数被括号括起来,并且在JavaScript中括号被重载为含义
对表达式进行分组以覆盖优先级:(x + y) * z
功能应用:f()
在函数前面加一个分号可以防止函数在括号与函数应用程序混淆时变成前面的参数。
考虑
1 2 3
| var x = 42
(function () { ... })() |
是相同的
1
| var x = 42(function () { ... })() |
但
1 2 3 4 5
| var x = 42
;
(function () { ... })() |
是相同的
1 2 3
| var x = 42;
(function () { ... })() |
-
只有在严重缩小时才会这样
-
@Neal,你能解释一下吗?我认为缩小与此完全正交。
-
@Neal它也等同于:尝试用return 1替换...然后在42之后添加分号并查看差异。
-
很有意思。我为@Josh所说的创造了一个小提琴,所以我可以亲眼看看会发生什么:http://jsfiddle.net/LK63x/。
-
@Neal,是的新行与它无关,如jsfiddle.net/vZvfG所示。换行仅影响JS中的受限制作:return,this,++,--,break,continue。
-
尽管并非所有IIFE都必须用括号括起来。 !function(){}()或"invoke!",function(){}()也可以正常工作,如果代码缩小,只需要前面的;。
-
@patrick dw,有趣。我没有在生产代码中看到这种模式。
我以无分号的方式编写所有JavaScript。由于自动分号插入(ASI),在每行末尾没有分号的情况下写入时,有一些特殊情况首先会"混淆":
使用运算符启动顶级表达式,在这种情况下,((开括号)与大多数其他运算符一样,可以继续前一个表达式,从而抑制"自动插入分号"。 (这通常仅在使用自调用函数时发生。)
开玩笑说#2:没有人! (只学习一条规则,你也可以享受没有额外分号的生活;-)
因为我以无分号的方式编写,所以我总是把它写成(函数表达式自然可以跨越多行):
在我的情况下,它不是关于"安全"或试图"发现错误"(老实说,如果你的风格是使用分号并且你忘记了分号,那么你已经在其他地方创建了错误并且写了一个;在"安全"的开始是hogwash)。没有;在我的情况下,它是为了与我所选择的风格的知识保持一致并且"知道"与操作员开始一行可以继续前一行的表达。
请参阅JavaScript:分号插入(您需要了解的所有内容)以获取详细信息(这是迄今为止我在该主题上看到的最佳文章)。
快乐的编码。
-
你要求麻烦,真的,依靠什么本质上是一种机制来掩盖草率编程。分号是有原因的。
-
@thepeer不,不,我不是真的。省略分号不是"草率编码"。请备份这些毫无根据的主张;在我的帖子中,我已经解释了以无分号风格书写时的"问题",并提供了如何编写从未出现过ASI问题的代码的规则。然后我解释为什么它与"安全"无关,并提供一个覆盖细节的资源的链接(查看链接中的return生产)。另一方面,引起这种反应的评论攻击了我的编码风格,并发表了一个我发现没有根据的陈述。不酷。
-
@thepeer虽然我在其他关于ASI的问题中解决了不同的"安全"问题,但在这个特定的答案中,我声称以分号所需的样式省略任何分号是不正确和不安全的 - 特别是因为并非总是如此准备继续排队,像一个人(像我一样)写一个无分号的风格是。因此,就"安全性"而言,这两种方法之间没有区别。现在,分号的一大优势是,如果不使用分号,许多工具/格式化程序会混淆。这与"草率编码"无关,但与工具有关。
-
@thepeer关于代码中"安全"的实际数字,我只有自己的经验。在很多年的JavaScript中,当我第一次碰到这个结构时,我被一个无分号的代码烧了一次。自从我开始使用规则#1以来,我没有任何与分号"遗漏"相关的内容 - 这是非常令人印象深刻的,不是吗? (我被return构造烧了好几次,但具有讽刺意味的是,这与以无分号格式书写无关。请参阅文章中的链接。)
-
还有其他规则。例如,"undefined" === typeof (function () { return /*newline*/ 42; })()。有关详细信息,请参阅限制性作品。
-
@MikeSamuel感谢您写出来:)链接文章中涵盖了该产品,并且在分号/不分号的情况下也是如此。这是一个有趣的生产语法本身,与; - 一个语句视图相反。
-
@pst,限制性作品不在您的规则1中。您需要一条规则2。
-
@MikeSamuel不,我没有。它与分号无关。人们需要"知道"即使用分号结束每个语句。因此,规则#1没有涵盖它,这是一个有缺陷的论点。
-
@pst,"undefined" === typeof (function () { return /*newline*/ 42; })()是正确的,因为在return之后插入了分号。
-
@MikeSamuel哦,我看到了令人困惑的事情。我打算用这个规则来涵盖用分号编写代码的无分号代码的情况。在任何情况下,这都包含在提供的资源中 - 我一直这么说,因为它是一个很好的阅读,并且将涵盖超过SO答案的意图 - 并且与分号一样无效。
-
@pst,这是另一种情况:如果你倾向于像condition && side_effect()那样写简写,那么/foo/i.test(x) && sideEffect()之后的/foo/i.test(x) && sideEffect()会变成var x = 42 / foo / i.test(x) && sideEffect()的等价物,所以顶级正则表达式也有问题,因为它们可能与除法运算符不明确。
-
@pst,公平的重新限制制作。
-
@MikeSamuel Touche。我想我只是"把二元运算符视为理所当然":D(那个正则表达式的例子是特别棘手的,但是表达式中的ick - 副作用?: - /)
-
@pst,是的(歧义是语法层次歧义,而/是词汇歧义。我同情你的整体观点 - 自从我开始编写Go代码以来,我发现我很欣赏一些分号插入的配方。 JavaScript的分号插入规则应用于具有常规词法语法的语言,这不会成为问题,但JavaScript的奇怪的标记化规则会导致更多的极端情况。
-
重写"ick - 表达式中的副作用?",写了很多bash的人倾向于生成看起来像bash的JS :)
-
@MikeSamuel再次看到Touche。我必须在我用尽点数之前停下来。
-
@pst我并没有指责你的草率编码;原谅我,如果这是它的阅读方式。我的意思是js解析器自动插入分号的原因最初 - 就像其他一些js特征一样(未声明的变量变成全局变量是另一个) - 因为js被视为一种hack-ish语言,应该是宽恕编码实践的原谅。我知道有一个让分号更加严谨的运动更加严谨;我反对它。事实上,我希望严格模式会在省略分号时抛出错误或至少发出警告。
-
@ user166390您的规则1不包括以[开头的语句。它并不常见,但如果您依赖ASI,这样的事情也会失败:var abc = [ 1, 2, 3, 4 ] /*newline*/ [ 'hello', 'world' ].forEach(function(it) { console.log(it) })
对我来说,半冒号在Internet Explorer 8中触发错误(或者至少是IETester所说的),并阻止ui选项卡正常工作。
错误消息是Invalid character in jquery.all.ui.js Line: 1. Char: 1。
我完全偶然发现了分号。
当我从;(function($)中删除;时,它起作用,看似没有副作用或功能丧失。
我正在使用Drupal,不知道这是否与此事有关。