Автоматическая вставка точек с запятой и возврат

Как вы, возможно, знаете, 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 утверждение в этой строке? Кто-нибудь может предоставить подробности об уровне реализации об этом?

3 ответа

Решение

Интерпретатор / компилятор javascript настолько умен, что вставляет автоматические точки с запятой только в том случае, если впоследствии существует допустимый Javascript.

Ваш код работает, потому что && b в существующем виде это недопустимое выражение - поэтому точка с запятой не вставляется после return a в результате чего:

return a && b && c;

Тем не мение:

return (undefined);//implicitely inserted
{
    ....
}

совершенно правильно, и именно поэтому точка с запятой вставляется.

Для полноты изложения ссылка на спецификацию: автоматическая вставка точки с запятой. Примеры стоит прочитать.

Не зависит от браузера / внедрения, но Section 7.9 Automatic Semicolon Insertion Спецификации языка ECMAScript стоит прочитать.

7.9 Автоматическая вставка точек с запятой

Некоторые операторы ECMAScript (пустой оператор, оператор переменной, оператор выражения, оператор do-while, оператор continue, оператор break, оператор return и оператор throw) должны заканчиваться точкой с запятой. Такие точки с запятой всегда могут быть явно указаны в исходном тексте. Однако для удобства такие точки с запятой могут быть исключены из исходного текста в определенных ситуациях. Эти ситуации описываются тем, что в этих ситуациях точки с запятой автоматически вставляются в поток токенов исходного кода.

7.9.1 Правила автоматической вставки точек с запятой Есть три основных правила вставки точек с запятой:

  1. Когда при синтаксическом анализе программы слева направо обнаруживается токен (называемый токеном-нарушителем), который не допускается никаким производством грамматики, тогда точка с запятой автоматически вставляется перед токеном-нарушителем, если один или несколько из следующих условия верны:

    • Токен-нарушитель отделен от предыдущего токена хотя бы одним LineTerminator.
    • Токен-нарушитель -}.
  2. Когда, когда программа анализируется слева направо, встречается конец входного потока токенов, и анализатор не может проанализировать входной поток токенов как одну завершенную программу ECMAScript, тогда точка с запятой автоматически вставляется в конце входной поток.

  3. Когда, когда программа анализируется слева направо, встречается токен, который допускается некоторым производством грамматики, но производство является ограниченным производством, и токен будет первым токеном для терминала или нетерминала, следующего сразу за аннотацией.?[здесь нет LineTerminator]? внутри ограниченного производства (и поэтому такой токен называется ограниченным токеном), и ограниченный токен отделяется от предыдущего токена хотя бы одним LineTerminator, после чего точка с запятой автоматически вставляется перед ограниченным токеном. Однако в предыдущих правилах есть дополнительное переопределяющее условие: точка с запятой никогда не вставляется автоматически, если точка с запятой будет затем проанализирована как пустая инструкция, или если эта точка с запятой станет одной из двух точек с запятой в заголовке инструкции for (см. 12.6.3). ПРИМЕЧАНИЕ. Ниже перечислены единственные ограниченные произведения в грамматике: PostfixExpression: LeftHandSideExpression [здесь нет LineTerminator] ++ LeftHandSideExpression [здесь нет LineTerminator] - ContinueStatement: continue [здесь нет LineTerminator] Identifier; BreakStatement: break [здесь нет LineTerminator] Идентификатор; ReturnStatement: return [здесь нет LineTerminator] Expression; ThrowStatement: throw [no LineTerminator here] Expression; Практический эффект этих ограниченных производств заключается в следующем: когда встречается токен ++ или -, когда синтаксический анализатор рассматривает его как постфиксный оператор, и между предыдущим токеном и токеном ++ или - встречается как минимум один LineTerminator, затем точка с запятой автоматически вставляется перед токеном ++ или -. Когда встречается токен продолжения, разрыва, возврата или броска и встречается LineTerminator перед следующим токеном, точка с запятой автоматически вставляется после токена продолжения, разрыва, возврата или броска. В результате получаются практические советы для программистов на ECMAScript: оператор postfix ++ или - должен находиться в той же строке, что и его операнд. Выражение в выражении return или throw должно начинаться с той же строки, что и токен 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, поскольку между b и ++ возникает LineTerminator. Источник

if (a > b)
else c = d

не является допустимым предложением ECMAScript и не изменяется автоматической вставкой точки с запятой перед токеном else, даже если в этот момент не применяется обработка грамматики, поскольку автоматически вставленная точка с запятой будет затем проанализирована как пустой оператор. Источник

a = b + c
(d + e).print()

не преобразуется автоматической вставкой точки с запятой, поскольку выражение в скобках, начинающееся со второй строки, можно интерпретировать как список аргументов для вызова функции:

a = b + c(d + e).print()

В тех случаях, когда оператор присваивания должен начинаться с левой круглой скобки, для программиста рекомендуется указывать явную точку с запятой в конце предыдущего оператора, а не полагаться на автоматическую вставку точек с запятой.

Ваше заявление о возврате будет работать правильно во всех браузерах, как указывает Кристоф. Я предпочитаю сделать это еще более явным, если не для компьютеров, но для людей, по крайней мере, разместив операторы и по-другому:

return a &&
       b &&
       c;

В этом случае никому не нужно тратить секунду, размышляя, не вызовут ли автоматические точки с запятой хаос. Я предпочитаю это только для JavaScript, ваш оригинальный код легче читать.

Другие вопросы по тегам