Por que o JavaScript precisa começar com ";"?

218

Recentemente, notei que muitos arquivos JavaScript na Web iniciam ;imediatamente após a seção de comentários.

Por exemplo, o código deste plugin jQuery começa com:

/**
 * 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( $ ){

Por que o arquivo precisa começar com a ;? Também vejo essa convenção nos arquivos JavaScript do servidor.

Quais são as vantagens e desvantagens de fazer isso?

TK.
fonte

Respostas:

352

Eu diria que, como os scripts geralmente são concatenados e compactados / compactados / enviados juntos, há uma chance do último cara ter algo como:

return {
   'var':'value'
}

no final do último script sem um ;no final. Se você tem um ;no início, é seguro, por exemplo:

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
Nick Craver
fonte
8
Você não pode realmente ter uma returndeclaração como a última coisa em um script, pode? Voltar ao nível superior não faz sentido. Teria que ser outra coisa, certo?
User2357112 suporta Monica
3
@ user2357112 Ainda mais, o código após uma returninstrução não é executado e, portanto, não faz sentido concatenar. Pelo menos está }faltando.
Robert
57

Acredito (embora não tenha certeza, portanto, não me avise) que isso garantiria que qualquer declaração anterior de um arquivo diferente fosse fechada. Na pior das hipóteses, essa seria uma declaração vazia, mas, na melhor das hipóteses, poderia evitar rastrear um erro nesse arquivo quando a declaração inacabada realmente veio de cima.

Jerry Bullard
fonte
9
Não tenho 100% de certeza, mas estou com você nesse caso, Jerry.
03:
12

Considere este exemplo:

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

O que acontecerá é que será avaliado assim:

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

Portanto, o que aestá retornando será tratado como uma função e tentado ser inicializado.

Isso ocorre principalmente para evitar erros ao tentar concaturar arquivos de multiplicação em um arquivo:

a.js

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

b.js

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

Se concatenarmos esses arquivos, isso causará problemas.

Portanto, lembre-se de colocar o seu ;na frente (e talvez também em alguns outros lugares. Btw. var a = 1;;;var b = 2;;;;;;;;;var c = a+b;é perfeitamente válido JavaScript

andlrc
fonte