Does any other language other than JavaScript have a difference between brace start locations (same line and next line)?
今天,当我随机阅读Javascript模式O'Reilly的书时,我发现了一件有趣的事情(参考第27页)。
在JavaScript中,在某些情况下,如果大括号的起始位置不同,则会有差异。
1 2 3 4 5 6 7 8 9 | function test_function1() { return { name: 'rajat' }; } var obj = test_function1(); alert(obj); //Shows"undefined" |
同时
1 2 3 4 5 6 7 8 | function test_function2() { return { name: 'rajat' }; } var obj = test_function2(); alert(obj); //Shows object |
JSfiddle演示
有没有其他语言有这样的行为?如果是这样的话,那么我肯定得改变我的习惯。
我主要关注PHP、C、C++、Java和Ruby。
任何不依赖分号(而是换行)来分隔语句的语言都可能允许这样做。考虑python:
1 2 3 4 5 6 7 8 9 10 | >>> def foo(): ... return ... { 1: 2 } ... >>> def bar(): ... return { 1: 2 } ... >>> foo() >>> bar() {1: 2} |
您可能可以在VisualBasic中构造类似的案例,但在我的头脑中,我无法理解如何使用VB,因为它对值的放置位置有很大的限制。但是,除非静态分析器抱怨无法访问的代码,否则以下内容应该有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Try Throw New Exception() Catch ex As Exception Throw ex.GetBaseException() End Try ' versus Try Throw New Exception() Catch ex As Exception Throw ex.GetBaseException() End Try |
从您提到的语言来看,Ruby具有相同的属性。PHP、C、C++和Java不仅仅是因为它们将新行丢弃为空白,而且需要分号来分隔语句。
下面是Ruby中的python示例中的等效代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | >> def foo >> return { 1 => 2 } >> end => nil >> def bar >> return >> { 1 => 2 } >> end => nil >> foo => {1=>2} >> bar => nil |
javascript解释器会在每行末尾自动添加一个
因此,基本上问题不在于大括号的位置(这里表示的是一个对象文本,而不是大多数语言中的代码块),而在于这个小的"特性",它迫使您的第一个示例使用
对于其他具有类似行为的语言,请查看Konrad的答案。
当然。谷歌的Go编程语言表现出非常相似的行为(尽管效果不同)。如前所述:
In fact, what happens is that the formal language uses semicolons, much as in C or Java, but they are inserted automatically at the end of every line that looks like the end of a statement. You don't need to type them yourself.
..snip...
This approach makes for clean-looking, semicolon-free code. The one surprise is that it's important to put the opening brace of a construct such as an if statement on the same line as the if; if you don't, there are situations that may not compile or may give the wrong result. The language forces the brace style to some extent.
私下里,我认为罗伯·派克只是想找个借口来要求一个真正的支撑方式。
这个问题的答案相当简单。任何具有"自动分号插入"的语言都可能在该行中遇到问题。这个问题
1 2 3 4 | return { name: 'rajat' }; |
..是JS引擎将在
fwiw,jslint报告了几种使用该语法的警告:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | $ jslint -stdin function foo(){ return { x:"y" }; } ^D (3): lint warning: unexpected end of line; it is ambiguous whether these lines are part of the same statement return ........^ (3): lint warning: missing semicolon { x:"y" }; ..^ (3): lint warning: unreachable code { x:"y" }; ..^ (3): lint warning: meaningless block; curly braces have no impact { x:"y" }; ..^ (3): lint warning: use of label { x:"y" }; .....^ (3): lint warning: missing semicolon { x:"y" }; ...........^ (3): lint warning: empty statement or extra semicolon { x:"y" }; ............^ 0 error(s), 7 warning(s) |
我遇到的第一种语言是awk(它也有语法"oddities"的部分;可选的分号、仅使用空格的字符串连接等等…)我认为DTrace设计人员(松散地基于awk的D语法)有足够的判断力不去复制这些特性,但我记不清这些特性。一个简单的例子(从我的Mac计算DTD中实体标记的数量):
1 2 3 4 5 6 7 | $ cat printEntities.awk # This prints all lines where the string ENTITY occurs /ENTITY/ { print $0 } $ awk -f printEntities.awk < /usr/share/texinfo/texinfo.dtd | wc -l 119 |
如果这个小脚本是用大括号自己一行写的,那么会发生以下情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $ cat printAll.awk # Because of the brace placement, the print statement will be executed # for all lines in the input file # Lines containing the string ENTITY will be printed twice, # because print is the default action, if no other action is specified /ENTITY/ { print $0 } $ awk -f printAll.awk < /usr/share/texinfo/texinfo.dtd | wc -l 603 $ /bin/cat < /usr/share/texinfo/texinfo.dtd | wc -l 484 $ |