Javascript 为什么行尾需要分号?
为什么这样做有效:Javascript 为什么行尾需要分号?,javascript,syntax,Javascript,Syntax,为什么这样做有效: a = [] a.push(['test']); (function() {alert('poop')})() 但这会导致错误“数字不是函数”: 唯一的区别是第2行末尾的分号。我已经写JavaScript很久了。我知道自动插入分号,但我不知道是什么导致了这个错误。我不是Javascript专家(甚至不是新手:),但如果将第二行和第三行结合起来,它在语法上仍然有效: a.push(['test'])(function() {alert('poop')})() 这是试图将a.
a = []
a.push(['test']);
(function() {alert('poop')})()
但这会导致错误“数字不是函数”:
唯一的区别是第2行末尾的分号。我已经写JavaScript很久了。我知道自动插入分号,但我不知道是什么导致了这个错误。我不是Javascript专家(甚至不是新手:),但如果将第二行和第三行结合起来,它在语法上仍然有效:
a.push(['test'])(function() {alert('poop')})()
这是试图将a.push(['test'])
的结果作为一个函数来处理,将一个函数传递给它。。。然后将结果也作为函数调用
如果两条语句可以按语法组合成一条语句,我怀疑需要分号,但这不是您想要的。a.push(['test'])
返回一个数字
然后尝试将数字作为函数调用,并将function(){alert('poop')}
作为唯一参数
因此,您的错误是,
number不是一个函数
看看这个链式函数调用的示例
a.push(['test'])(function() {alert('poop')})()
看起来眼熟吗?这是编译器/解释器查看代码的方式
细节
下面是用于描述调用表达式的语法的一部分
CallExpression :
MemberExpression Arguments
CallExpression Arguments
CallExpression [ Expression ]
CallExpression . IdentifierName
或者更正式地说
CallExpression(
CallExpression(
CallExpression(
MemberExpression( a.push ),
Arguments( (['test']) )
),
Arguments( (function() {alert('poop')}) )
),
Arguments( () )
)
调用表达式(
调用表达式(
调用表达式(
成员表达式(a.push),
参数((['test']))
),
参数((函数(){alert('poop')}))
),
参数(())
)
.push()的结果是返回数组的大小,在本例中为1。函数周围的圆括号使Javascript解析器认为您正在尝试调用:
1( function() {alert('poop')} )()
或者您试图调用一个名为1
的函数,并将匿名函数作为参数,然后作为函数执行返回。因为
a.push(['test'])(function() {alert('poop')})()
是一个有效的JavaScript表达式。如果一些相邻的行可以粘在一起形成一个有效的JavaScript表达式,您的JavaScript引擎将把它们粘在一起
虽然它是一个有效的JavaScript表达式,a.push
返回一个不是函数的数字,当您尝试调用不是函数的东西时,它返回您看到的错误。a.push(['test'])
将返回数组的长度,一个数字。如果后面没有分号,编译器将解释后面的自调用函数的左括号,就像您试图将该数字作为带参数的函数执行一样。假设它返回的长度为7,那么这里发生的事情就好像你写了:
7 (function() {alert('poop')})();
因此出现错误“number不是函数”,因为它不知道如何将7作为函数调用。在某些情况下,不需要将其作为令牌分隔符,而只用于提高可读性:
空白字符用于提高源文本的可读性,并将标记(不可分割的词汇单位)彼此分离,但在其他方面则无关紧要。空白可能出现在任意两个标记[…]之间,但不能出现在任何其他类型的标记中
在这种情况下,a.push(['test'])
和(function(){alert('poop')})(
之间的空白不是令牌分隔符,因此不重要。所以这相当于:
a.push(['test'])(function() {alert('poop')})()
由于a
引用了长度为0的空数组,因此调用a.push(['test'])
将一个元素附加到a
并返回a.length
的更新值,即1
:
1(function() {alert('poop')})()
剩下的就是历史。在某些情况下,分号不会自动插入,这就是其中之一。你应该总是在行尾加上分号,以避免出现这样的问题。值得一读:每个人都会大便,甚至是JavaScript。可能重复的啊,非常有意义!谢谢你把它清理干净!现在我可以滥用alert()函数了。。。
a.push(['test'])(function() {alert('poop')})()
1(function() {alert('poop')})()