Перейти к содержанию

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

Хоть JavaScript и имеет синтаксис, подобный языкам семейства C, он при этом не принуждает вас ставить точки с запятой в исходном коде — вы всегда можете их опустить.

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

var foo = function() {
} // ошибка разбора, ожидается точка с запятой
test()

Происходит вставка и парсер пытается снова.

var foo = function() {
}; // ошибки нет, парсер продолжает
test()

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

Как это работает

Приведённый код не содержит точек с запятой, так что места для их вставки остаются на совести парсера:

(function(window, undefined) {
    function test(options) {
        log('тестируем!')

        (options.list || []).forEach(function(i) {

        })

        options.value.test(
            'здесь передадим длинную строчку',
            'и ещё одну на всякий случай'
        )

        return
        {
            foo: function() {}
        }
    }
    window.test = test

})(window)

(function(window) {
    window.someLibrary = {}

})(window)

Ниже представлен результат игры парсера в "угадалки".

(function(window, undefined) {
    function test(options) {

        // не вставлена точка с запятой, строки были объединены
        log('тестируем!')(options.list || []).forEach(function(i) {

        }); // <- вставлена

        options.value.test(
            'здесь передадим длинную строчку',
            'и ещё одну на всякий случай'
        ); // <- вставлена

        return; // <- вставлена, в результате
                //    оператор return разбит на два блока
        { // теперь парсер считает этот блок отдельным

            // метка и одинокое выражение
            foo: function() {}
        }; // <- вставлена
    }
    window.test = test; // <- вставлена

// снова объединились строки
})(window)(function(window) {
    window.someLibrary = {}; // <- вставлена

})(window); //<- вставлена

Замечание: Парсер JavaScript некорректно обрабатывает оператор return, за которым следует новая строка; кстати, причина может быть и не в автоматической вставке точек с запятой, но это в любом случае нежелательный побочный эффект

Парсер радикально подменил поведение изначального кода, а в определённых случаях он сделал абсолютно неправильные выводы.

"Висящие" скобки

Если парсер встречает "висящую" скобку, то он не вставляет точку с запятой.

log('тестируем!')
(options.list || []).forEach(function(i) {})

Такой код трансформируется в строку

log('тестируем!')(options.list || []).forEach(function(i) {})

Чрезвычайно высоки шансы, что log возвращает не функцию; таким образом, эта строка вызовет TypeError с сообщением о том, что undefined не является функцией.

Заключение

Настоятельно рекомендуем никогда не забывать ставить точку с запятой; также рекомендуется оставлять скобки на одной строке с соответствующим оператором и никогда не опускать их для выражений с использованием if / else. Оба этих совета не только повысят читабельность вашего кода, но и предотвратят от изменения поведения кода, произведённого парсером втихую.