JavaScript在“for”语句中将“;”作为第一个参数传递

6

我一直在研究jQuery源代码,当检查jQuery.fn.extend函数时,我注意到以下内容:

for ( ; i < length; i++ ){
    code
}

为什么在开头会有一个分号;?同样,我注意到一些JavaScript库也是这样开头的:
; (function (){ ...

没有任何先前的代码。

为什么?这在语法上是如何正确的?

谢谢。


参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for - Felix Kling
可能在第一种情况下,i已经被初始化了。所以初始化是不必要的,这就是为什么它保持为空的原因。 - Innovation
4个回答

7
JavaScript的for循环有三个可选参数,因此您可以省略所有三个参数。
在您的代码中,
for( ; i < length; i++) 

第一个参数被省略了。分号;没有作为参数传递。分号;只是一个分隔符。 for循环的语法如下:


for( [optional parameter 1] ; [optional parameter 2] ; [optional parameter 3] )

OR

for ([initialization] ; [condition] ; [final-expression])

所以下面的语句在语法上是正确的。
for( ; i < length; i ++ )  // first parameter is omitted
for( ; i < length; ) // first and third parameters are omitted
for( ; ; ) // all parameters are omitted

5

这两个代码片段是无关的。

第一个是一个空语句。一个 for 循环需要3个语句;如果你在循环之前初始化变量,则不需要在内部进行初始化,但语句必须存在,因此出现了空语句:

var i=0;
for (; i<10; i++) {}

一个典型的例子是for(;;),与while(true)相同但更短。

第二段代码是IIFE(立即调用函数表达式)的开头。开头的分号是为了避免其他JavaScript文件缺少分号而导致的连接错误,否则IIFE可能会被解释为函数调用,例如:

// file1.js
var f = function(){} // oops
// file2.js
(function(){})();

如果文件确实包括了最后的分号,那么你就会得到一个空语句,这是可以的。

第二部分真的会发生危险吗?.js文件(以及<script>块)不是分别解析的吗? - JLRishe
是的,这是一个真正的危险,已经发生过,将会继续发生,并且这是一个非常难以追踪的错误。如果你处于一个严肃的生产环境中,所有的JavaScript都会被压缩和合并,并在一个单独的脚本文件中进行传输。我认为UglifyJS有一些功能或者东西可以避免这种情况,但不确定... - elclanrs
通过在开发中使用JSHint和其他一些工具,您可以降低此类问题发生的可能性,如果您以前遇到过这种情况。 - elclanrs

2
这两个例子没有关联。
在第一个例子中,一个 for 语句总是有三个组成部分:初始化、条件和增量语句。这三个部分都是可选的,所以代码 for( ; i < length; i++) 在循环之前选择不初始化任何内容。
空语句 ; 是完全有效的,它在语法上没有任何问题。

1
这是两个独立的主题,但为了按顺序解决它们:
在 for 循环中,您有三个部分:初始化、条件和增量/减量部分。
第一部分,即初始化,可以直接在 for 循环中编写,例如:
for (var i = 0; i < length; i++) {

或者,可以在它之前加上:


var i = 0;
for (; i < length; i++) {

两者的意思是相同的,只是看起来略有不同。
关于最后一段代码中的; (function(){ ...,前面的;只是一个空语句。在JavaScript中,分号仅用于表示语句的结尾,本身是有效的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接