O que faz o ponto-e-vírgula principal nas bibliotecas JavaScript?

156

Em várias bibliotecas JavaScript, vi essa notação no início:

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

Embora eu esteja perfeitamente confortável com a sintaxe da "função imediatamente executada"

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

Fiquei me perguntando para que serve o ponto e vírgula principal. Tudo o que eu pude pensar é que é um seguro. Ou seja, se a biblioteca estiver incorporada em outro código de buggy, ela servirá como um tipo de "lombada" a "última declaração termina aqui no mais recente".

Tem alguma outra funcionalidade?

Boldewyn
fonte

Respostas:

140

Ele permite concatenar com segurança vários arquivos JavaScript em um, para atendê-lo mais rapidamente como uma solicitação HTTP.

Kornel
fonte
16
Mas não seria necessário, se todos os arquivos fossem codificados corretamente, seria?
Boldewyn
8
Não: no seu exemplo, você receberia (function(){...})()(function(){...})().
Aaron Digulla
8
Que eu quis dizer com 'codificado corretamente', que a cada extremidades da biblioteca com a quantidade correta de ponto e vírgula à direita ...
Boldewyn
6
Sim Boldewyn, mas isso simplesmente não é o caso.
Mathias Bynens
13
Dois arquivos mal codificados não serão adequados apenas pelo fato de um terceiro arquivo conter essa correção suja. Por que o concatenador não pode adicionar ponto e vírgula extra entre os arquivos no resultado?
Dávid Horváth
30

A melhor resposta foi dada na pergunta, então vou escrever isso aqui para maior clareza:

O líder ;na frente das expressões de função chamadas imediatamente existe para evitar erros ao anexar o arquivo durante a concatenação a um arquivo que contém uma expressão que não foi finalizada corretamente com a ;.

A melhor prática é finalizar suas expressões com ponto e vírgula, mas também use o ponto e vírgula principal como uma salvaguarda.

princípio holográfico
fonte
Por que também encerrar suas expressões com ponto e vírgula, se você estiver usando ponto e vírgula defensivo? Ou você tem a chance de contar com ponto e vírgula no final de cada linha ou usa ponto e vírgula defensivo. Ao fazer as duas coisas, as pessoas concluem incorretamente que há uma razão para fazer as duas coisas. O conselho para usar ponto e vírgula defensivo é bom; o conselho para substituir também todas as instâncias de "\n"com ";\n"não faz sentido.
Vladimir Kornea
4
@VladimirKornea: porque você não está sempre usando apenas suas próprias bibliotecas :)
jvenema
@jvenema Não sei por que você acha que isso faz a diferença.
Vladimir Kornea
6
Porque você não pode confiar no código de outra pessoa seguindo suas convenções. Código defensivo e então você não precisa.
jvenema
1
@ VladimirKornea Você também pode pensar nisso como defensivo, se quiser - ele se defende contra o código de outra pessoa que nem sempre começa com ponto e vírgula defensivo.
precisa
26

Em geral, se uma declaração começa com (, [, /, + ou -, existe a chance de que possa ser interpretada como uma continuação da declaração antes. As declarações que começam com /, + e - são bastante raras na prática , mas instruções começando com (e [não são incomuns, pelo menos em alguns estilos de programação JavaScript. Alguns programadores gostam de colocar um ponto-e-vírgula defensivo no início de qualquer instrução, para que ela continue funcionando corretamente, mesmo que a instrução antes de ser modificado e um ponto-e-vírgula de encerramento anterior removido:

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

Fonte:

JavaScript: The Definitive Guide, 6ª edição

Faraz Kelhini
fonte
9

Isso é conhecido como ponto e vírgula à esquerda.

Seu principal objetivo é proteger-se do código anterior que foi fechado incorretamente, o que pode causar problemas. Um ponto e vírgula impedirá que isso aconteça. Se o código anterior foi fechado incorretamente, nosso ponto-e-vírgula corrigirá isso. Se foi fechado corretamente, nosso ponto e vírgula será inofensivo e não haverá efeitos colaterais.

bvmCoder
fonte
7

Uma resposta de uma linha é concatenar com segurança vários arquivos JavaScript. Usar um ponto e vírgula não levanta um problema.

Suponha que você tenha várias funções:

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

Na concatenação, pode parecer com:

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

Mas se você adicionar um ponto-e-vírgula antes da função, será semelhante a:

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

Portanto, adicionando a ;, cuida se alguma expressão não é finalizada corretamente.

Exemplo 2

Suponha que você tenha um arquivo JavaScript com uma variável:

var someVar = "myVar"

Outro arquivo JavaScript com alguma função:

(function(){})()

Agora, na concatenação, parecerá

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

Com um ponto e vírgula, será semelhante a:

var someVar = "myVar";(function(){})()
brk
fonte
4

É bom quando você reduz o código JavaScript. Evita erros inesperados de sintaxe.

VOCÊS
fonte
Como o quê? O ponto-e-vírgula tem algum significado para o código a seguir ou é apenas para o código de buggy hipotético mesclado na frente da biblioteca real?
Boldewyn
Nesse código sozinho, não há significado especial, mas quando esse código está no meio de outros códigos e quando você o reduz para uma linha única, pode haver erros inesperados, como (1) ponto e vírgula está faltando nas linhas anteriores, (1 ) anterior também é funções, então será () () () (), quando houver erro, difícil de depurar, não podemos dizê-lo de buggy, porque antes minify seu bom funcionamento.
VOCÊ
1
Mas certamente é responsabilidade do minificador lidar com isso corretamente. Os minificadores de buggy são a norma hoje em dia?
Vladimir Kornea