¿Por qué el JavaScript necesita comenzar con ";"?

218

Recientemente me di cuenta de que muchos archivos JavaScript en la Web comienzan ;inmediatamente después de la sección de comentarios.

Por ejemplo, el código de este complemento jQuery comienza con:

/**
 * 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 qué el archivo necesita comenzar con a ;? También veo esta convención en archivos JavaScript del lado del servidor.

¿Cuáles son las ventajas y desventajas de hacer esto?

TK
fuente

Respuestas:

352

Diría que dado que los scripts a menudo se concatenan y minimizan / comprimen / envían juntos, existe la posibilidad de que el último tipo haya tenido algo como:

return {
   'var':'value'
}

al final del último guión sin un ;al final. Si tiene un ;inicio al suyo, es seguro, por ejemplo:

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
fuente
8
En realidad, no puede tener una returndeclaración como lo último en un script, ¿verdad? Volver al nivel superior no tiene sentido. Tendría que ser algo más, ¿verdad?
user2357112 es compatible con Monica
3
@ user2357112 Aún más, el código después de una returndeclaración no se ejecuta, por lo que no tiene sentido concatenar. Al menos hay un }desaparecido.
Robert
57

Creo (aunque no estoy seguro, así que no me salte encima) que esto aseguraría que cualquier declaración previa de un archivo diferente esté cerrada. En el peor de los casos, esta sería una declaración vacía, pero en el mejor de los casos podría evitar tratar de rastrear un error en este archivo cuando la declaración inacabada realmente vino de arriba.

Jerry Bullard
fuente
99
No estoy 100% seguro, pero estoy contigo en esto, Jerry.
okw
12

Considere este ejemplo:

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

Lo que sucederá es que se evaluará así:

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

Entonces, lo que asea ​​que regrese será tratado como una función que se intentará inicializar.

Esto es principalmente para evitar errores al tratar de concat multiplicar archivos en un solo archivo:

a.js

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

b.js

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

Si combinamos estos archivos juntos, causará problemas.

Por lo tanto, recuerde poner su ;frente (y quizás también algunos otros lugares. Por cierto. var a = 1;;;var b = 2;;;;;;;;;var c = a+b;es perfectamente válido JavaScript

andlrc
fuente