Нужны ли точки с запятой после литерального присваивания объекта в JavaScript?

Следующий код иллюстрирует присваиваемый литерал объекта, но без точки с запятой:

var literal = {
    say: function(msg) { alert(msg); }
}
literal.say("hello world!");

Это кажется законным и не выдает предупреждение (по крайней мере, в Firefox 3). Это полностью законно или существует строгая версия JavaScript, где это запрещено?

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

7 ответов

Решение

Технически, JavaScript во многих ситуациях не использует точки с запятой.

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

Переводчик автоматически вводит точки с запятой, поэтому вы можете оставить их, если захотите. В комментариях кто-то утверждал, что

Точки с запятой не являются обязательными с такими утверждениями, как break/continue/throw

но это неверно. Они не являются обязательными; что на самом деле происходит, так это то, что терминаторы строки влияют на автоматическую вставку точек с запятой; это тонкая разница.

Вот остальные стандарты на вставку точек с запятой:

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

YUI Compressor и dojo shrinksafe должны прекрасно работать без точек с запятой, поскольку они основаны на полном синтаксическом анализаторе JavaScript. Но Пакер и JSMin не будут.

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

var literal = {
    say: function(msg) { alert(msg); }
}
(function() {
    // ....
})();

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

Интерпретаторы JavaScript выполняют так называемую "вставку точки с запятой", поэтому, если допустима строка без точки с запятой, точка с запятой будет тихо добавлена ​​в конец оператора, и ошибки не возникнет.

var foo = 'bar'
// Valid, foo now contains 'bar'
var bas =
    { prop: 'yay!' }
// Valid, bas now contains object with property 'prop' containing 'yay!'
var zeb =
switch (zeb) {
  ...
// Invalid, because the lines following 'var zeb =' aren't an assignable value

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

return {
    prop: 'yay!'
}
// The object literal gets returned as expected and all is well
return
{
    prop: 'nay!'
}
// Oops! return by itself is a perfectly valid statement, so a semicolon
// is inserted and undefined is unexpectedly returned, rather than the object
// literal. Note that no error occurred.

Подобные ошибки могут быть невероятно трудными для поиска, и хотя вы не можете гарантировать, что этого никогда не произойдет (поскольку я не знаю, как отключить вставку точек с запятой), такого рода ошибки легче идентифицировать, когда вы ясно доносите свои намерения последовательно используя точки с запятой. Это и явное добавление точек с запятой обычно считается хорошим стилем.

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

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

В JavaScript нет точек с запятой как "необязательных". Скорее, он имеет строгие правила в отношении автоматической вставки точек с запятой. Точки с запятой не являются обязательными с такими утверждениями, как break, continue, или же throw, Обратитесь к спецификации языка ECMA для получения более подробной информации; в частности, 11.9.1, правила автоматической вставки точек с запятой.

Точка с запятой не обязательна. Некоторые люди предпочитают следовать соглашению всегда заканчивать точкой с запятой вместо того, чтобы разрешать JavaScript делать это автоматически при переносе строк, но я уверен, что вы найдете группы, выступающие в любом направлении.

Если вы хотите написать "правильный" JavaScript, я бы посоветовал протестировать вещи в Firefox с javascript.options.strict (доступ через about:config) установлено в true. Он может не поймать все, но он должен помочь вам убедиться, что ваш код JavaScript более совместим.

Используйте JSLint, чтобы поддерживать JavaScript в чистоте и порядке

JSLint говорит:

Ошибка:

Подразумеваемый глобальный: оповещение 2

Проблема в строке 3, символ 2: отсутствует точка с запятой.

}

Это недопустимо (см. Пояснение ниже) код JavaScript, поскольку присваивание - это просто регулярное утверждение, ничем не отличающееся от

var foo = "bar";

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

Если вы хотите писать правильный код JavaScript, введите точку с запятой:-)

Согласно спецификации ECMAscript, http://www.ecma-international.org/publications/standards/Ecma-262.htm, точки с запятой автоматически вставляются, если они отсутствуют. Это делает их необязательными для автора сценария, но подразумевает, что они необходимы для интерпретатора. Это означает, что ответом на исходный вопрос является "Нет", они не требуются при написании сценария, но, как отмечают другие, рекомендуется по разным причинам.

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