Операторы автоматической вставки и возврата с запятой
Как вы, возможно, знаете, ECMAscript пытается быть умным и будет автоматически вставлять точки с запятой, если вы не пишете их явно. Простой пример
function foo() {
var bar = 5
return bar
}
будет работать, как ожидалось. Но есть некоторые оговорки, если вы полагаетесь на это. Если мы перепишем эту функцию так:
function foo() {
var bar = 5
return
{
bar: bar
}
}
.. эта функция теперь вернет undefined
, потому что интерпретатор будет вставлять эту точку с запятой сразу после оператора return
(это причина, по которой вы всегда должны вставлять фигурные скобки в той же строке, что и оператор).
Однако, зная все это, мне теперь интересно, насколько безопасен оператор return
, такой как следующий, в браузерах и версиях
function foo() {
var a = true,
b = true,
c = false;
return a
&& b
&& c;
}
Я только что написал аналогичную return statement
в производственной среде. Просто потому, что я знал о "проблемах" с ECMAscript, не очень-то умных о вставке с запятой, мне интересно сейчас, если этот код работает на 100%. В моих первых тестах на FF/Chrome/IE (последние версии) это выглядит совершенно нормально, но действительно ли это?
Используется ли автоматическая точка с запятой "пробуждение", если в этой строке есть что-то еще, кроме оператора return
? Может ли кто-нибудь предоставить информацию об уровне реализации на этом уровне?
Ответы
Ответ 1
Javascript-интерпретатор/компилятор настолько умен, чтобы вставлять автоматические точки с запятой, если после этого есть действительный Javascript.
Ваш код работает, потому что && b
в его синтаксисе не является допустимым выражением - почему после точки return a
не добавляется точка с запятой, в результате чего:
return a && b && c;
Однако:
return (undefined);//implicitely inserted
{
....
}
является абсолютно допустимым, и поэтому точка с запятой вставлена.
Для полноты ссылки на спецификацию: автоматическая вставка точки с запятой. Примеры заслуживают внимания.
Ответ 2
Не зависит от браузера/имплантации, но Section 7.9 Automatic Semicolon Insertion
ECMAScript Language Specification стоит прочитать.
7.9 Автоматическая точка с запятой
Некоторые операторы ECMAScript (пустой оператор, оператор переменной, оператор выражения, do-while
оператор, оператор continue, оператор break, оператор return и оператор throw) должны быть
заканчивается точкой с запятой. Такие точки с запятой могут всегда отображаться явно в исходном тексте. Для
однако, такие точки с запятой могут быть опущены из исходного текста в определенных ситуациях. Эти
ситуации описываются, говоря, что точки с запятой автоматически вставлены в токен исходного кода
поток в этих ситуациях.
7.9.1 Правила автоматической вставки точки с запятой
Существует три основных правила вставки точки с запятой:
-
Когда, когда программа анализируется слева направо, появляется токен (называемый оскорбительным токеном), который
не допускается никаким производством грамматики, то точка с запятой автоматически вставлена перед
оскорбительный токен, если выполняется одно или несколько из следующих условий:
- Оскорбительный токен отделен от предыдущего токена, по крайней мере, одним LineTerminator.
- Оскорбительный токен -}.
-
Когда, когда программа анализируется слева направо, встречается конец входного потока токенов
и синтаксический анализатор не может проанализировать поток входных токенов как одну полную программу ECMAScript, затем
точка с запятой автоматически вставлена в конец входного потока.
-
Когда, когда программа анализируется слева направо, появляется токен, который разрешен некоторыми
производство грамматики, но производство является ограниченным производством, и токен будет первым
токен для терминала или нетерминала сразу после аннотации? [no LineTerminator здесь]? в пределах
ограниченное производство (и поэтому такой токен называется ограниченным токеном), а ограниченный токен
отделенный от предыдущего токена, по крайней мере, одним линейным тестером, то точка с запятой автоматически
вставлен перед ограниченным токеном.
Тем не менее, существует дополнительное условие переопределения для предыдущих правил: точка с запятой никогда не вставлена
автоматически, если точка с запятой затем анализируется как пустой оператор или если эта точка с запятой станет
одна из двух точек с запятой в заголовке оператора for (см. 12.6.3).
ПРИМЕЧАНИЕ. Ниже перечислены только ограниченное производство грамматики:
PostfixExpression:
LeftHandSideExpression [нет LineTerminator здесь] ++
LeftHandSideExpression [нет LineTerminator здесь] -
ContinueStatement:
continue [no LineTerminator here] Идентификатор;
BreakStatement:
break [no LineTerminator here] Идентификатор;
ReturnStatement:
return [no LineTerminator here] Expression;
ThrowStatement:
throw [no LineTerminator here] Expression;
Практический эффект этих ограниченных производств заключается в следующем:
Когда встречается символ ++ или - токен, когда парсер будет рассматривать его как постфиксный оператор и, по крайней мере, один
LineTerminator произошел между предыдущим токеном и символом ++ или -, тогда точка с запятой автоматически
вставлен перед символом ++ или -.
Когда встречается маркер continue, break, return или throw, и перед ним возникает LineTerminator
следующий токен, точка с запятой автоматически вставлена после маркера continue, break, return или throw.
В результате практические рекомендации программистам ECMAScript:
Оператор postfix ++ или - должен отображаться в той же строке, что и его операнд.
Выражение в операторе return или throw должно начинаться с той же строки, что и маркер возврата или броска.
Идентификатор в инструкции break или continue должен находиться в той же строке, что и маркер break или continue.
7.9.2 Примеры автоматической точки с запятой
Источник
{ 1 2 } 3
не является допустимым предложением в грамматике ECMAScript, даже с правилами автоматической вставки точки с запятой. В
контраст, источник
{ 1
2 } 3
также не является допустимым предложением ECMAScript, но преобразуется автоматической точкой с запятой в
следующее:
{ 1
;2 ;} 3;
который является допустимым предложением ECMAScript.
Источник
for (a; b
)
не является допустимым предложением ECMAScript и не изменяется с помощью автоматической точки с запятой, поскольку
точка с запятой необходима для заголовка оператора for. Автоматическая установка с запятой никогда не вставляет одну из
две точки с запятой в заголовке оператора for.
Источник
return
a + b
преобразуется автоматической вставкой с запятой в следующее:
return;
a + b;
ПРИМЕЧАНИЕ. Выражение a + b не рассматривается как значение, возвращаемое оператором return, поскольку
LineTerminator отделяет его от возвращаемого токена.
Источник
a = b
++c
преобразуется автоматической вставкой с запятой в следующее:
a = b;
++c;
ПРИМЕЧАНИЕ. токен ++ не рассматривается как оператор постфикса, применимый к переменной b, поскольку возникает LineTerminator
между b и ++.
Источник
if (a > b)
else c = d
не является допустимым предложением ECMAScript и не изменяется с помощью автоматической точки с запятой перед токеном else,
даже несмотря на то, что в этот момент не производится никакого производства грамматики, поскольку автоматически вставленная точка с запятой
затем анализируется как пустой оператор.
Источник
a = b + c
(d + e).print()
не преобразуется автоматической точкой с запятой, так как выражение в скобках, которое начинается с
вторая строка может быть интерпретирована как список аргументов для вызова функции:
a = b + c(d + e).print()
В том случае, если оператор присваивания должен начинаться с левой скобки, это хорошая идея для
программист, чтобы обеспечить явную точку с запятой в конце предыдущего утверждения, а не полагаться на
автоматическая точка с запятой.
Ответ 3
Ваш оператор возврата будет корректно работать во всех браузерах, как указывает Кристоф. Я предпочитаю сделать его еще более явным, если не для компьютеров, а для людей, по крайней мере, поместив их и операторов по-разному:
return a &&
b &&
c;
В этом случае никто не должен тратить время на размышления, если автоматические полуколоны будут разрушать хаос. Я предпочитаю это только для JavaScript, ваш исходный код легче читать.