Имеет ли какой-либо другой язык, кроме JavaScript, разницу между местоположениями начала скобок (такая же строка и следующая строка)?
Сегодня, когда я случайно читал книгу JavaScript O'Reilly, я нашел одну интересную вещь (стр. 27 для справки).
В Javascript в некоторых случаях существует разница, если местоположение начала скобки отличается.
function test_function1() {
return
{
name: 'rajat'
};
}
var obj = test_function1();
alert(obj); //Shows "undefined"
Пока
function test_function2() {
return {
name: 'rajat'
};
}
var obj = test_function2();
alert(obj); //Shows object
JSfiddle Demo
Есть ли у любого другого языка такое поведение? Если да, то мне пришлось бы изменить свою привычку наверняка..:)
Меня в основном интересуют PHP, C, С++, Java и ruby.
Ответы
Ответ 1
Любой язык, который не полагается на точки с запятой (но вместо этого на новые строки), чтобы разграничить заявления, потенциально позволяет это. Рассмотрим Python:
>>> def foo():
... return
... { 1: 2 }
...
>>> def bar():
... return { 1: 2 }
...
>>> foo()
>>> bar()
{1: 2}
Возможно, вы сможете построить аналогичный случай в Visual Basic, но не в верхней части моей головы. Я не могу понять, как из-за того, что VB довольно ограничительный, где могут быть размещены значения. Но следующее должно работать, если статический анализатор не жалуется на недостижимый код:
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, С++ и Java не просто потому, что они отбрасывают новую строку как пробел и требуют, чтобы точки с запятой ограничивали выражения.
Вот эквивалентный код из примера Python в Ruby:
>> def foo
>> return { 1 => 2 }
>> end
=> nil
>> def bar
>> return
>> { 1 => 2 }
>> end
=> nil
>> foo
=> {1=>2}
>> bar
=> nil
Ответ 2
Переводчик JavaScript автоматически добавляет ;
в конце каждой строки, если он не находит его (за некоторыми исключениями, не попадая сюда:).
Таким образом, в основном проблема заключается не в местоположении скобок (которое здесь представляет собой литерал объекта, а не блок кода, как на большинстве языков), но эта небольшая "функция", которая заставляет ваш первый пример return ;
= > undefined
. Вы можете проверить поведение return
в спецификации ES5.
Для других языков с аналогичным поведением проверьте ответ Konrad.
Ответ 3
Конечно. Язык i0 > демонстрирует очень похожее поведение (хотя и с разными эффектами). Как объясняется там:
Фактически, происходит то, что на официальном языке используются точки с запятой, как и на C или Java, но они автоматически вставлены в конце каждой строки, которая похожа на конец инструкции. Вам не нужно вводить их самостоятельно.
.. чик...
Этот подход обеспечивает чистоту, без кода с запятой. Одно удивление состоит в том, что важно разместить открытую фигуру конструкции, такую как оператор if в той же строке, что и if; если вы этого не сделаете, есть ситуации, которые не могут компилироваться или могут дать неправильный результат. Язык в некоторой степени заставляет стиль фигурной скобки.
Втайне, я думаю, что Роб Пайк просто хотел оправдания, чтобы потребовать One True Brace Style.
Ответ 4
Ответ на этот вопрос довольно прост. Любой язык, который имеет "автоматическую точку с запятой", может оказаться в затруднительном положении на этой линии. Проблема с этим
return
{
name: 'rajat'
};
.. является то, что движок js вставляет точку с запятой после оператора return;
(и, следовательно, возвращает undefined
). Этот пример является хорошей причиной для открытия фигурных скобок всегда с правой стороны и никогда не с левой стороны. Поскольку вы уже правильно заметили, если в одной строке есть фигурная скобка, интерпретатор заметит это и не может вставить точку с запятой.
Ответ 5
FWIW, JSLint сообщает о нескольких предупреждениях с этим синтаксисом:
$ 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)
Ответ 6
Первым языком, на котором я столкнулся, был awk (который также имеет свою долю синтаксиса "странности", необязательные полуколоны, конкатенацию строк с использованием только пробелов и т.д.)
Я думаю, что дизайнеры DTrace, основанные на синтаксисе D свободно на awk, имели достаточный смысл НЕ копировать эти функции, но я не могу вспомнить с головы.
Простой пример (подсчет количества тегов ENTITY в DTD с моего Mac):
$ 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
Если этот маленький script был написан с помощью скобки на отдельной строке, это произойдет:
$ 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
$