Точки с запятой в JavaScript не обязательны. Точка с запятой в JavaScript разделяет сообщество: некоторые предпочитают использовать их всегда несмотря ни на что, а другим нравится их избегать.
Почему же JavaScript не требует строгого использования точки с запятой? Потому, что он сам виртуально добавляет их в нужные места. Процесс, который делает это, называется автоматической вставкой точки с запятой (Automatic Semicolon Insertion (ASI)) и описан в стандарте языка.
Важно знать правила использования точек с запятой, чтобы избежать написания кода, который будет генерировать ошибки из-за того, что ведет себя не так, как вы ожидаете.
Принцип этой функции состоит в том, чтобы обеспечить некоторую снисходительность при оценке синтаксиса программы JavaScript путем концептуальной вставки пропущенных точек с запятой. Концептуально, так как программа успешно выполняет синтаксический анализ на основе этого правила, а не фактически изменяет код и добавляет точки с запятой.
Из спецификации:
Некоторые операторы ECMAScript должны заканчиваться точкой с запятой. Такие точки с запятой всегда могут быть явно указаны в исходном тексте.
Но далее говорится:
Однако для удобства в определенных ситуациях в исходном тексте могут быть опущены такие точки с запятой.
Вот простой пример кода, согласно спецификации, эти операторы переменных должны заканчиваться точкой с запятой:
var a = 1
var b = 2
var c = 3
Эти синтаксические ошибки исправлены при анализе, и код будет считаться следующим:
var a = 1;
var b = 2;
var c = 3;
Парсер JavaScript автоматически добавит точку с запятой, когда во время синтаксического анализа исходного кода обнаружит следующие конкретные ситуации:
return
на отдельной строке;break
на отдельной строке; continue
на отдельной строке; throw
на отдельной строке. Основываясь на этих правилах, вот несколько примеров:
const hi = 'Привет'
const name = 'Петя'
const hiYou = hi + ', ' + name
['a', 'b', 'c'].forEach((letter) => console.log(letter))
Вы получите сообщение об ошибке: error: Uncaught TypeError: Cannot read property 'forEach' of undefined, потому что на основе 1 правила JavaScript пытается интерпретировать код как:
const hi = 'Привет'
const name = 'Петя'
const hiYou = hi + ', ' + name['a', 'b', 'c'].forEach((letter) => console.log(letter))
Такая строка (1 + 2).toString()
выведет "3", но вот такой код:
const a = 1
const b = 2
const c = a + b
(a + b).toString()
вместо этого вызывает исключениеerror: Uncaught TypeError: b is not a function
, потому что JavaScript пытается интерпретировать его как:
const a = 1
const b = 2
const c = a + b(a + b).toString()
Очень часто встречается проблема, связанная с ключевым словом return (правило 4):
var a = function() {
var b = 'ответ'
return
{
answer: b
}
}
console.log(a());
Можно было бы ожидать, что возвращаемое значение этой функции будет объектом, содержащим свойство answer
, но это не так.
Этот код синтаксически неверен, и его лучше рассматривать как синтаксическую ошибку. Грамматическое правило для оператора return
выглядит следующим образом:
return [no LineTerminator here] Expression ;
Т.е. после ключевого слова return
не должно быть перехода на новую строку. Но автоматическая вставка точки с запятой устраняет эту ошибку, преобразуя оператор return в следующий код:
return;
{
answer: b
}
Поэтому вернется значение undefined
, а не объект. Вставка точки с запятой не исправт ситуацию, но вот удаление перевода на друную строку заставит наш код работать правильно:
var a = function() {
var b = 'ответ'
return {
answer: b
}
}
console.log(a());
Можно подумать, что этот код выведет в консоль 0:
1 + 1
-1 + 1 === 0 ? console.log(0) : console.log(2)
но вместо этого он выведет 2, потому что JavaScript согласно правила 1 интерпретирует это как:
1 + 1 -1 + 1 === 0 ? console.log(0) : console.log(2)
Вот еще один пример. В следующем фрагменте кода пропустили запятую после переменной a :
var a
b = 2;
console.log(a);
console.log(b);
Вместо того, чтобы выдавать синтаксическую ошибку, точка с запятой добавляется следующим образом:
var a;
b = 2;
console.log(a);
console.log(b);
Эта проблема немного более тонкая. Включение точки с запятой приведет к объявлению переменной b в глобальной области видимости. Это вызовет ошибку "Uncaught ReferenceError: b is not defined" в строгом режиме.
Ключевым моментом является то, что эта может иметь очень тонкие побочные эффекты, которые трудно выявить в большом коде.
Код:
function add(a,b) {return a+b}
Будет рассматриваться интрепретатором (правило 2) как:
function add(a,b) {return a+b;}
Вот несколько случаев, когда точки с запятой не нужны:
if (...) {...} else {...}
for (...) {...}
while (...) {...}
Но требуется согласно стандарта для
do {...} while (...);
После объявления функции точка с запятой также не нужна:
function myfunc (arg) {...}
Но нужна после объявления функционального выражения:
let myfunc = function (arg) {
...
};
Если вы напишите:
var i = 0;
do { i++; console.log(i) } while ( i < 5 )
Технически это недопустимая программа, так как конечная точка с запятой отсутствует, но ASI (автоматическая вставка точки с запятой) обработает ее в вид:
var i = 0;
do { i++; console.log(i) } while ( i < 5 );
Можно писать и с использованием точек с запятой и без. В разных компаниях свои стили. Так в требованиях по стилю кодированя на Javascript в Google использование автоматической вставки точки с запятой запрещено. Некоторые компании опускают необязательные точки с запятой.
Если же вы собираетесь писать свой JavaScript код без дополнительных точек с запятой хорошо бы знать, что делает ASI. Например, сжатие или минификация может привести к тому, что ваш код может выдасть ошибку, потому что эти программы часто полагаются на точки с запятой. Если пишете без точек с запятой, то не никогда не начинайте строку со скобок, они могут быть объединены с предыдущей строкой для формирования вызова функции или ссылки на элемент массива или же перед такой строкой ставьте точку с запятой:
const a = 1
const b = 2
const c = a + b
;(a + b).toString()
Кроме того, может быть труднее отлаживать без точек с запятой, поскольку ваш код может объединяться вместе, а вы этого не осознаёте. Если вы поместите разрыв строки там, где его не должно быть, ASI может вмешаться и принять точку с запятой, даже если ее не должно быть.
Распространенное заблуждение состоит в том, что "use strict"
(строгий режим) JavaScript подавляет функцию ASI. Это не так. Единственный способ избежать этой функции — убедиться, что точка с запятой всегда вставляется в правильном месте. Наиболее эффективный способ обнаружения отсутствующих в JavaScript запятой осуществляется с помощью инструмента статического анализа кода, таких как JSHint или JSLint или можно использовать компилятор Javascript babeljs.io.