Сегодня, когда я случайно читал книгу О'Рейли по шаблонам JavaScript, я обнаружил одну интересную вещь (стр. 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
Есть ли в других языках такое поведение? Если так, то мне обязательно придется менять привычку .. :)
Меня больше всего беспокоят PHP, C, C ++, Java и ruby.
javascript
language-agnostic
programming-languages
language-design
Раджат Сингхал
источник
источник
Ответы:
Любой язык, который не полагается на точки с запятой (а вместо этого на новые строки) для разделения операторов, потенциально допускает это. Рассмотрим 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, C ++ и Java не делают этого просто потому, что они отбрасывают новую строку как пробелы и требуют точки с запятой для разделения операторов.
Вот эквивалентный код из примера Python на Ruby:
>> def foo >> return { 1 => 2 } >> end => nil >> def bar >> return >> { 1 => 2 } >> end => nil >> foo => {1=>2} >> bar => nil
источник
Throw
иex.GetBaseException()
отдельные логические линии. В частности, поскольку Basic исторически использует строки для разграничения своих операторов, «ошибка», скорее всего, будет ситуацией, когда программист думает, что он создал новый оператор в новой логической строке, но не сделал этого.Интерпретатор JavaScript автоматически добавляет
;
в конец каждой строки, если он не находит его (за некоторыми исключениями, здесь они не попадают :).Таким образом, в основном проблема заключается не в расположении фигурных скобок (которые здесь представляют литерал объекта, а не в блоке кода, как в большинстве языков), а в этой маленькой «особенности», которая заставляет ваш первый пример использовать
return ;
=>undefined
. Вы можете проверить поведениеreturn
в спецификации ES5 .Для других языков с аналогичным поведением ознакомьтесь с ответом Конрада .
источник
undefined
возвращает. Я написал немного о других языках с префиксом afaik , так что относитесь к нему с недоверием :).Несомненно. Язык программирования Google go демонстрирует очень похожее поведение (хотя и с разными эффектами). Как объясняется там:
Втайне я думаю, что Роб Пайк просто хотел оправдание, чтобы потребовать стиль One True Brace.
источник
Ответить на этот вопрос довольно просто. Любой язык, в котором есть "автоматическая вставка точки с запятой", может вызвать ошибку в этой строке. Проблема с этим
return { name: 'rajat' };
.. заключается в том, что движок js вставит точку с запятой после
return;
оператора (и, следовательно, вернетundefined
). Этот пример - хорошая причина открывать фигурные скобки всегда с правой стороны, а не с левой. Поскольку вы уже правильно заметили, если в той же строке есть фигурная скобка, интерпретатор заметит это и не сможет вставить точку с запятой.источник
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)
источник
Первым языком, на котором я столкнулся с этим, был 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
Если бы этот небольшой сценарий был написан с фигурной скобкой на отдельной строке, то произошло бы следующее:
$ 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 $
источник