Что делает ведущая точка с запятой в библиотеках JavaScript?


156

В нескольких библиотеках JavaScript я видел эту запись в самом начале:

/**
 * Library XYZ
 */
;(function () {
  // ... and so on

Хотя мне вполне комфортно с синтаксисом «немедленно выполняемая функция»

(function(){...})()

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

Есть ли у него другие функциональные возможности?


Ответы:


140

Он позволяет безопасно объединить несколько файлов JavaScript в один, чтобы он быстрее обслуживался как один HTTP-запрос.


16
Но не было бы необходимости, если бы все файлы были правильно закодированы, не так ли?
Болдевин

8
Нет: в вашем примере вы получите (function(){...})()(function(){...})().
Аарон Дигулла

8
Что я имел в виду «правильно закодировано», что каждая библиотека заканчивается правильным количеством конечных точек с запятой ...
Boldewyn

6
Да, Болдевин, но это просто не тот случай.
Матиас Биненс

13
Два плохо закодированных файла не подойдут только потому, что третий файл содержит это грязное исправление. Почему конкатенатор не может добавить лишние точки с запятой между файлами в результате?
Давид Хорват

30

На самом деле лучший ответ был дан в вопросе, поэтому я просто напишу это здесь для ясности:

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

Лучшая практика - заключать выражения в точки с запятой, но также использовать начальную точку с запятой в качестве гарантии.


Зачем также заканчивать свои выражения точками с запятой, если вы используете защитные точки с запятой? Либо вы пользуетесь возможностью полагаться на точки с запятой, присутствующие в конце каждой строки, либо используете защитные точки с запятой. Выполнение того и другого заставляет людей ошибочно заключать, что есть причина сделать то и другое. Совет использовать защитные точки с запятой хорош; совет также заменить каждый экземпляр "\n"с ";\n"не имеет никакого смысла.
Владимир Корнеа

4
@VladimirKornea: потому что вы не всегда используете только свои собственные библиотеки :)
jvenema

@jvenema Я не знаю, почему ты думаешь, что это имеет значение.
Владимир Корнеа

6
Потому что вы не можете полагаться на чужой код, следуя вашим правилам. Код защиты и тогда вам не нужно.
Jvenema

1
@VladimirKornea Вы можете думать об этом как о защите, если хотите - она ​​защищает от чужого кода, который не всегда начинается с защитной точки с запятой.
Натан

26

В общем случае, если оператор начинается с (, [, /, + или -, есть вероятность, что его можно интерпретировать как продолжение предыдущего оператора. Утверждения, начинающиеся с /, + и -, довольно редки на практике , но операторы, начинающиеся с (и [, не являются чем-то необычным, по крайней мере, в некоторых стилях программирования JavaScript. Некоторым программистам нравится ставить защитную точку с запятой в начале любого такого оператора, чтобы он продолжал работать правильно, даже если оператор перед его изменением и удалением завершающей точки с запятой:

var x = 0 // Semicolon omitted here
;[x,x+1,x+2].forEach(console.log) // Defensive ; keeps this statement separate

Источник:

JavaScript: Полное руководство, 6-е издание


9

Это называется ведущей точкой с запятой.

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


7

Ответ в одну строку - безопасно объединить несколько файлов JavaScript. Использование точки с запятой не вызывает проблем.

Предположим, у вас есть несколько функций:

IIFE 1

(function(){
  // The rest of the code
})(); // Note it is an IIFE

IIFE 2

(function(){
   // The rest of the code
})(); // Note it is also an IIFE

При объединении это может выглядеть так:

(function(){})()(function(){})()

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

;(function(){})();(function(){})()

Таким образом, добавляя a ;, он заботится о том, чтобы любое выражение не было правильно завершено.

Пример 2

Предположим, у вас есть файл JavaScript с переменной:

var someVar = "myVar"

Еще один файл JavaScript с некоторой функцией:

(function(){})()

Теперь на конкатенации это будет выглядеть

var someVar = "myVar"(function(){})() // It may give rise to an error

С точкой с запятой это будет выглядеть так:

var someVar = "myVar";(function(){})()

4

Это хорошо, когда вы минимизируете код JavaScript. Это предотвращает непредвиденные синтаксические ошибки.


Как что? Имеет ли точка с запятой какое-либо значение для следующего кода или это только для гипотетического глючного кода, слитого перед реальной библиотекой?
Болдевин

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

1
Но, конечно же, ответственность за правильное решение этой проблемы лежит на минификаторе. Являются ли глючные минифификаторы нормой в наши дни?
Владимир Корнеа
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.