Почему JavaScript должен начинаться с «;»?

218

Недавно я заметил, что многие JavaScript-файлы в Интернете начинаются ;сразу после раздела комментариев.

Например, код этого плагина jQuery начинается с:

/**
 * jQuery.ScrollTo
 * Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 9/11/2008                                      
 .... skipping several lines for brevity...
 *
 * @desc Scroll on both axes, to different values
 * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
 */
;(function( $ ){

Почему файл должен начинаться с ;? Я вижу это соглашение и в серверных JavaScript-файлах.

Каковы преимущества и недостатки этого?

ТЗ.
источник

Ответы:

352

Я бы сказал, поскольку сценарии часто объединяются и минимизируются / сжимаются / отправляются вместе, есть вероятность, что у последнего парня было что-то вроде:

return {
   'var':'value'
}

в конце последнего сценария без ;конца. Если у вас есть ;в начале, это безопасно, пример:

return {
   'var':'value'
}
;(function( $ ){ //Safe (still, screw you, last guy!)

return {
   'var':'value'
}
(function( $ ){ //Oh crap, closure open, kaboom!

return {
   'var':'value'
};
;(function( $ ){ //Extra ;, still safe, no harm
Ник Крейвер
источник
8
Вы не можете на самом деле иметь returnутверждение как последнюю вещь в сценарии, не так ли? Возвращение на верхний уровень не имеет смысла. Это должно быть что-то еще, верно?
user2357112 поддерживает Monica
3
@ user2357112 Тем более, код после того, как в returnзаявлении не получает выполняется, так что не имеет смысла для конкатенации. По крайней мере, там }пропал.
Роберт
57

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

Джерри Буллард
источник
9
Я не уверен на 100%, но я с тобой в этом, Джерри.
О
12

Рассмотрим этот пример:

function a() {
  /* this is my function a */
}
a()
(function() {
  /* This is my closure */
})()

Что произойдет, так это то, что это будет оценено следующим образом:

function a() {
  /* this is my function a */
}
a()(function() {})()

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

Это в основном для предотвращения ошибок при попытке объединить файлы в один файл:

a.js

function a() {
  /* this is my function a */
}
a()

b.js

(function() {
  /* This is my closure */
})()

Если мы объединяем эти файлы вместе, это вызовет проблемы.

Поэтому не забывайте ставить ;перед собой (и, возможно, также в нескольких других местах. Btw. var a = 1;;;var b = 2;;;;;;;;;var c = a+b;это совершенно правильный JavaScript

andlrc
источник