Por que a recente mudança para remover / omitir ponto e vírgula do Javascript?


80

Parece estar na moda recentemente omitir ponto e vírgula do Javascript. Há uma publicação de blog há alguns anos, enfatizando que em Javascript, ponto- e- vírgula é opcional e a essência da publicação parecia ser que você não deveria se preocupar com elas porque são desnecessárias. O post, amplamente citado, não fornece razões convincentes para não usá-los, apenas que deixá-los de fora tem poucos efeitos colaterais.

Até o GitHub pulou na onda sem ponto e vírgula, exigindo sua omissão em qualquer código desenvolvido internamente, e um recente commit no projeto zepto.js por seu mantenedor removeu todos os pontos e vírgulas da base de código. Suas principais justificativas foram:

  • é uma questão de preferência para a equipe dele;
  • menos digitação

Existem outras boas razões para deixá-los de fora?

Francamente, não vejo razão para omiti-los e certamente não há motivo para voltar ao código para apagá-los. Isso também vai contra ( anos de ) práticas recomendadas , pelas quais eu realmente não compro o argumento "cult de carga". Então, por que todo o recente ódio por ponto e vírgula? Existe uma escassez iminente? Ou isso é apenas a última moda do Javascript?


2
"anos de prática recomendada" referem-se uma questão de lista negra tag urnas SO que improvável torna autoritário para suportar qualquer tipo de opinião
mosquito

24
@gnat só porque as pessoas odeiam a pergunta sobre SO, não a torna uma fonte menos válida de opinião das pessoas.
Ryathal 29/03/12

3
@gnat Perguntas que são "oficialmente consideradas inadequadas no StackOverflow" às vezes são consideradas autorizadas pela comunidade de especialistas. Triste mas verdadeiro.
MarkJ

4
@gnat A questão da lista negra na verdade tem alguns exemplos muito interessantes de por que omitir o ;pode quebrar seu código. Então, eu diria que é uma referência útil para esta pergunta.
Andrés F.

1
Isso pode estar relacionado à crescente importância dos descolados no início dos anos 2010.
Alex

Respostas:


62

Suponho que minha razão seja a menos convincente: eu programo em muitas linguagens diferentes ao mesmo tempo (Java, Javascript, PHP) - que exigem ';' então, em vez de treinar meus dedos e olhos, o ';' não é necessário para javascript, eu sempre adiciono o ';'

A outra razão é a documentação: adicionando o ';' Estou dizendo explicitamente para mim mesmo onde espero que a declaração termine. Então, novamente, eu uso {} o tempo todo também.

Todo o argumento da contagem de bytes acho irritante e inútil:

1) para bibliotecas comuns como jquery: use o CDN do Google e a biblioteca provavelmente já estará no cache do navegador

2) versão suas próprias bibliotecas e configurá-los para serem armazenados em cache para sempre.

3) gzip e minimize se for realmente necessário.

Mas, na verdade, quantos sites têm como maior gargalo de velocidade a velocidade de download de seu javascript? Se você trabalha para um dos 100 melhores sites como twitter, google, yahoo, etc. talvez. O resto de nós deve se preocupar apenas com a qualidade do código e não com as guerras religiosas em ponto e vírgula.


3
Eu acho que o oposto também pode ser verdade. À medida que o python se torna mais popular para a Web, é mais fácil fazer com que seu JS se assemelhe a python.
Ben DeMott

4
Tente, mas o mesmo byte warriors estaria atrás de mim por espaço em branco desnecessário no início das linhas. (Eu também teria erros de Javascript, porque confiaria na regra de indentação do Python em vez de usar {}
Pat

6
Se a redução da contagem de bytes for importante, você terá algo que minimiza os arquivos o máximo possível. Se ainda não vale a pena usar um minimizador, não vale a pena se preocupar em remover ';' para economizar na contagem de bytes.
Lawsonfogle 16/04/2015

3
a contagem de bytes não é necessariamente necessariamente reduzida; na verdade, ela pode ser aumentada, pois uma nova linha geralmente é (nem sempre) na verdade dois caracteres (nova linha seguida de retorno de carro); portanto, em sua forma mais eficiente em termos de espaço, o novo Uma vez que a linha será caractere igual a um ponto e vírgula de um caractere (se você compactar todo o seu código JS em uma linha, isso geralmente é feito para o código JS implementado, não para o código-fonte de desenvolvimento).
ALXGTV

Os seres humanos precisam de indentação para entender o aninhamento profundo, o que requer mais bytes que ponto e vírgula. Ponto-e-vírgula são desperdícios distraídos de pressionamentos de tecla.
precisa

39

Facilita o encadeamento de métodos e compromete o limpador de diferenças

Então, digamos que eu estou jQuerying e eu tenho

$('some fancy selector')
  .addClass()
  .attr();

Se eu quiser adicionar coisas e manter pequeno o diff de confirmação baseado em linhas , tenho que adicioná-lo acima de attr. Portanto, é um pensamento mais longo do que apenas "adicionar no final". E quem quer pensar? =)

$('some fancy selector')
  .addClass()
  // new method calls must go here
  .attr();

Mas, quando eu soltar o ponto-e-vírgula, posso acrescentar e chamar de dia

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate()
+   .click()

Além disso, se eu decidir sair do último método, não preciso reatribuir o ponto-e-vírgula e poluir meu commit novamente.

  $('some fancy selector')
    .addClass()
    .attr()
    .animate()
-   .click()

Contra o uggo

  $('some fancy selector')
    .addClass()
    .attr()
+   .animate();
-   .animate()
-   .click();

37
Esse é o caso de uso de nicho IMO.
JBRWilkinson

9
Mas interessante, no entanto.
317 Jonathan

8
Você pode ter ponto e vírgula no final de uma nova linha recuada como a linha de partida. Então você copia e reordena as coisas como desejar. Isso também fecha bem a cadeia.
Nux

11
Sou apenas eu quem me pergunta por que alguém se importaria com a aparência das diferenças de seus commits? Como regra geral, as pessoas leem código, não diffs.
Jules

11
@Jules, diferenças mais limpas significam que as fusões têm mais chances de sucesso.
Joeytwiddle 14/02

22

ponto e vírgula em JavaScript são opcionais

Minha razão pessoal para não usar ponto e vírgula é o TOC.

Quando uso ponto-e-vírgula, esqueço 2% deles e tenho que verificar / adicioná-los constantemente.

Quando não uso ponto-e-vírgula, nunca coloco um acidentalmente para nunca ter que verificar / removê-lo.


3
Um bom. Fui queimado por uma ou duas linhas sem ponto e vírgula em um arquivo semicolonizado.
31412 Jonathan

3
Existem analisadores (por exemplo, GeSHi) que não analisarão seu código corretamente se não houver ponto e vírgula. Você poderia dizer que os humanos não cometerão tais erros ... Mas, sério - se toda a sua equipe conseguir lembrar onde ponto e vírgula absolutamente precisa ser colocado, você realmente acha que eles se lembrarão disso sem o café da manhã? E eles codificarão em muitos estados de espírito. Tenha certeza disso.
Nux

16

Recentemente, escrevi um analisador / analisador de JavaScript, onde tive que implementar meticulosamente o ASI e também tenho uma cópia do JavaScript de Crockford : The Good Parts na minha estante, que defende sempre o uso de ponto e vírgula. A intenção era boa, mas nem sempre ajuda na prática.

Obviamente, as pessoas que escrevem estruturas como jQuery, zepto etc. são mestres de sintaxe JavaScript e, portanto, sabem a diferença entre:

return
{
    status: true
};

e

return {
    status: true
};

O JavaScript, embora poderoso, também é uma linguagem para iniciantes e boa sorte para explicar isso a alguém que está apenas aprendendo o que é um forloop. Como a introdução de uma nova habilidade para a maioria das pessoas, há algumas coisas mais complexas que você não deseja explicar imediatamente; então, em vez disso, você decide instilar um "culto à carga" em certas coisas, apenas para tirá-las do papel. Portanto, você tem duas opções ao ensinar um iniciante a escrever JavaScript:

  1. Diga a eles "siga esta regra e não pergunte o porquê", dizendo-lhes para colocar um ponto e vírgula sempre no final de cada linha. Infelizmente, isso não ajuda no exemplo acima, ou em qualquer outro exemplo em que o ASI atrapalhe. E o Sr. ou a Sra. Programador iniciante ficam confusos quando o código acima falha.
  2. Diga a eles "siga estas duas regras e não pergunte o porquê", dizendo-lhes para não se incomodarem com ponto-e-vírgula no final de cada linha e, em vez disso, sempre a) Siga returncom a {e eb) Quando uma linha começar com a (, prefira com um ;.

A escolha da opção 2 é um conjunto melhor de regras de "cult de carga" a serem seguidas (resultará em muito poucos bugs relacionados ao ASI) e, mesmo que você tenha uma compreensão profunda do tópico, terá menos caracteres desnecessários na tela.


8
Tudo bem, eu vou morder. Ajude-me a entender a diferença de sintaxe entre os dois exemplos acima. Meu olho destreinado vê apenas uma diferença na formatação.
Jesse C. Slicer

9
Ou, por outro lado, me deparei com a resposta por puro acidente. No primeiro exemplo, o returné considerado uma declaração solitária e o final da linha é equivalente a um ponto e vírgula. O segundo exemplo realmente retorna o objeto. Tricksy.
Jesse C. Slicer

9
Eu não acho que posso concordar com a idéia de que o JavaScript é uma linguagem para iniciantes, existem inúmeras inconsistências e efeitos surpreendentes no JavaScript que não têm explicações simples. OMI, uma linguagem para iniciantes não seria assim, eu chamaria o JavaScript de uma linguagem intermediária.
Ryathal 29/03/12

2
@ Ryathal Eu entendo o que você está dizendo, mas chamá-lo de idioma intermediário me faz pensar em quais idiomas ele intermedia. Você faz parecer que é um passo em uma jornada para outra coisa e não um destino por si só.
Racheet 13/05

9
Ponto de esclarecimento: o returnexemplo é realmente uma exceção ao comportamento normal do JS, que consiste em tentar juntar linhas quando um ponto e vírgula é omitido. return, break, E continuetodos exibem este comportamento excepcional em que uma nova linha de fuga é sempre interpretada como um fim de instrução. (A fonte é o "JavaScript: O Guia Definitivo" de Flanagan, pp25-26). Pessoalmente, luto pela idéia de "código de menor surpresa". Deixar ponto-e-vírgula fora tende a resultar em mais surpresas do que qualquer coisa (geralmente eu também mantenho meu aparelho cacheado, mesmo para declarações simples).
Kyle

16

Não existe sobrecarga de informações, apenas design incorreto.

- Edward Tufte

É uma regra geral no design gráfico deixar de fora elementos e ornamentos desnecessários para reduzir o ruído.

Menos elementos visuais na tela significam menos trabalho para o cérebro analisar as informações úteis reais.

let foo = 1

vs.

let /* variable */ foo = 1; // EOL

Um exemplo exagerado, é claro, mas ilustra o princípio geral: Elementos visuais adicionais devem ser adicionados se e somente se servirem a um propósito. Então, ponto e vírgula serve a um propósito?

Os motivos históricos para usar ponto e vírgula no JavaScript foram:

  • Manter semelhança com C / Java
  • Evite problemas de compatibilidade com navegadores e ferramentas mal escritos
  • Ajudando humanos e máquinas a detectar erros de código
  • A inserção automática de ponto e vírgula acarreta uma penalidade de desempenho

Os problemas de compatibilidade são praticamente um não-problema hoje. Linters modernos podem detectar erros de código da mesma forma, sem ponto e vírgula. A semelhança com C / Java / PHP ainda pode ser considerada (veja a resposta aceita por Pat), mas apenas porque outras linguagens contêm elementos de sintaxe supérfluos não significa que devemos mantê-las em JavaScript, principalmente porque muitas outras linguagens (Coffeescript, Python, Ruby, Scala, Lua) não precisam deles.

Fiz um teste rápido para ver se havia uma penalidade de desempenho no V8. Este é o Io.js que analisa um arquivo JavaScript de 41 MB (Lodash repetido 100 vezes) com ponto e vírgula e depois com ponto e vírgula removidos:

$ time node lodashx100.js
node lodashx100.js  2.34s user 1.30s system 99% cpu 3.664 total
$ time node lodashx100s.js
node lodashx100s.js  2.34s user 1.15s system 99% cpu 3.521 total

Todo mundo precisa decidir seu próprio estilo de codificação preferido para seus projetos, mas não vejo mais nenhum benefício tangível no uso de ponto e vírgula; portanto, para reduzir o ruído visual, parei.


Eu contrariaria esse argumento de deixar de fora elementos desnecessários na carga que a mente precisa fazer para adicionar novamente na sintaxe opcional. Agora o ponto-e-vírgula não é uma enorme tensão mental se omitido. Esse é um problema que experimentei com Ruby e Scala. Quando se torna uma cadeia de chamadas com chamadas dentro das chamadas, e todas elas omitem todos os parênteses, é um fardo separá-las.
Seamus

8

Escolher uma convenção de programação é efetivamente o mesmo que escolher um subconjunto do idioma de destino. Todos fazemos isso pelos motivos habituais: legibilidade do código, capacidade de manutenção, estabilidade, portabilidade etc. - enquanto potencialmente sacrificamos a flexibilidade. Esses motivos são reais para negócios.

Razões como "salvar pressionamentos de tecla" e "programadores devem aprender as regras de JavaScript" são razões comerciais marginais, por isso têm pouco peso prático.

No meu caso, eu precisava acelerar o JavaScript muito rapidamente, então aproveitar um subconjunto limitado da linguagem era a minha vantagem. Então, escolhi o subconjunto JSLint do JavaScript, ativei o JSLinter dos aplicativos Rockstar no Eclipse para as configurações mais restritivas que pude suportar e não olhei para trás.

Sou grato por poder evitar os detalhes da diferença entre "==" e "===", ou os detalhes da inserção de ponto e vírgula, porque eu já tenho uma lista de tarefas de milha alta e esses detalhes não ajudar a realizar esses trabalhos um segundo antes.

É claro que a coisa mais importante sobre uma convenção é a consistência, e pensar nela como um subconjunto de idiomas ajuda a reforçar esse imperativo. E, embora isso possa não ajudar a responder à pergunta do OP, acho que pode ajudar no enquadramento prático dela.


5

Uma pergunta bastante antiga, no entanto, estou surpreso que ninguém tenha mencionado:

Minificação: se você minificar um trecho de JavaScript que não encerre explicitamente as instruções com um caractere ponto-e-vírgula, poderá ter dificuldade em descobrir o que há de errado com um trecho que estava funcionando antes da minificação e agora não funciona.

Ambiguidade: ponto -e-vírgula é opcional, é verdade; entretanto, ao eliminá-los do código-fonte, você pode deixar alguns cenários ambíguos para o analisador decidir por si próprio. Se você estiver escrevendo 100 linhas de código para uma loja on-line, sim, talvez isso não importe, mas tarefas mais sérias exigiriam 100% de clareza.

Há muito tempo, li uma analogia muito boa sobre outra coisa, mas também é verdade neste caso: (No nosso caso) Eliminar os pontos e vírgulas é como atravessar em um sinal vermelho. Você pode ficar bem no final ou pode ser atropelado por um caminhão.

Por que está se tornando mais popular hoje em dia?

Pessoalmente, acredito que a execução de JavaScript no lado do servidor teve muitos efeitos na própria comunidade JavaScript. No nosso caso, obviamente ninguém reduzirá o JavaScript no lado do servidor (como o código-fonte não deve ser enviado para o navegador da Web do cliente), portanto, não ter ponto-e-vírgula parece muito mais seguro, o que é verdade; no entanto, os outros desenvolvedores que aprendem com esses livros, artigos e vídeos, infelizmente, descartam o fato de que o JavaScript no lado do servidor não é exatamente o mesmo que o JavaScript no lado do cliente.


Os minificadores podem sair em novas linhas de caractere único ou inserir ponto e vírgula quando o ponto e vírgula não estiver presente sem uma penalidade de tamanho. Não sei quais (se houver) minifiers fazem isso. O perigo ainda existe em pelo menos alguns deles, então seu argumento ainda é válido na prática.
sai em 12/07/2015

3

Existem boas razões para mantê-los.

Eles não são realmente opcionais, o JS pode adicioná-los novamente com inserção automática de ponto e vírgula quando estão ausentes, mas isso não é a mesma coisa.

O JavaScript de Douglas Crockford: The Good Parts diz em duas ocasiões separadas que é uma má idéia. A inserção automática de ponto-e-vírgula pode ocultar erros no seu programa e cria ambiguidade.

JSLint não aprova.


3

O JavaScript não precisa de ponto e vírgula para encerrar as declarações há mais de uma década. Isso ocorre porque os caracteres de nova linha são considerados terminadores de instrução (acredito que isso também seja mencionado nas primeiras especificações do ECMAScript). Realmente faz muito sentido, especialmente porque não há realmente uma boa razão [do que eu saiba] por que o JavaScript precisaria usar frequentemente ponto-e-vírgula, mas não outras linguagens declarativas interpretadas como Ruby ou Python.

Exigir ponto-e-vírgula pode tornar mais fácil escrever um analisador para um idioma, mas se todo intérprete disponível suportar a omissão de ponto-e-vírgula, qual é exatamente o ponto?

O que se resume é o conhecimento de um programador: se você sabe que pode omitir um ponto-e-vírgula, sinta-se à vontade para fazê-lo, entendendo que pode ou não haver uma consequência. Os seres humanos são máquinas de tomada de decisão e quase todas as decisões requerem algum compromisso ou troca. A desvantagem de apenas colocar ponto-e-vírgula em todo o seu código (mesmo em locais onde eles não são necessários) é que seu código se torna menos legível (dependendo de quem você pergunta) e o JSLint não reclama (quem se importa) ) Por outro lado, a vantagem de omitir ponto-e-vírgula é o fato de que 90% dos programadores de JavaScript o castigam por isso, mas você pode acabar gostando de escrever JavaScript mais por causa disso.

O que soa melhor para você; tomar decisões informadas ou tomar decisões cegas / mentalidade de rebanho?


Eu ficaria interessado em saber por que isso recebeu votos negativos. JavaScript não precisa de ponto-e-vírgula para finalizar declarações; certamente pode usá-los, mas eles não são de forma alguma um requisito. Se fossem necessárias, as explicações de mais ninguém funcionariam. O fato (sim, um fato) de que você pode escrever um aplicativo JavaScript inteiro com poucos ou nenhum ponto e vírgula demonstra isso. Além disso, não vejo como entender como uma ferramenta funciona e usar o próprio raciocínio para tomar decisões é de alguma forma censurável em contraste com "apenas faça". Isso é conhecido como religião.
Ravenstine 27/08/2015

Não diminuí o voto, mas o problema pode ser que isso não esteja correto como está escrito. As novas linhas não são consideradas terminadores de instruções em javascript. É possível deixar ponto e vírgula por causa de um recurso chamado inserção automática de ponto e vírgula que permite corrigir erros de análise automaticamente em determinadas circunstâncias. As pessoas que defendem ponto e vírgula argumentam que muitos programadores de javascript parecem entender mal essa regra. Sua postagem parece ser um argumento a seu favor nessa perspectiva. (Para ser justo, eu principalmente concordo com sua tese, mas por razões diferentes)
Tim Seguine

@ TimSeguine Sim, eu escrevi isso de volta antes de entender melhor. Ainda não acho objetivamente errado não usar ponto e vírgula, desde que as pessoas entendam exatamente o que estão fazendo. Eu deveria refazer meu post, ou talvez me livrar dele, já que outras pessoas entraram na conversa sobre isso. Obrigado pela crítica educada! :)
Ravenstine

2

Eu tenho duas teorias:

A)

A questão sobre essa escolha é que, antigamente, quando JSLint etc. eram aplicáveis, você optava por gastar uma grande quantidade de tempo capturando erros de sintaxe obscuros ou uma quantidade razoável de tempo aplicando uma política de padrões em código.

No entanto, à medida que avançamos mais em direção ao código orientado ao teste de unidade e à integração contínua, a quantidade de tempo (e interação humana) necessária para capturar um erro de sintaxe diminuiu enormemente. Os comentários dos testes indicam rapidamente se o seu código está funcionando conforme o esperado, muito antes de chegar perto do usuário final. Por que perder tempo adicionando verbosidade opcional?

B)

Programadores preguiçosos farão de tudo para facilitar suas próprias vidas a curto prazo. Menos digitação -> menos esforço -> mais fácil. (além disso, não precisar de ponto e vírgula evitará esticar o dedo anelar da mão direita, evitando RSIness).

(NB, eu discordo da idéia de omitir algo que desambigua uma afirmação).


1
O jshint ainda é uma ferramenta importante.
Raynos 29/03/12

Quanto disambiguating uma declaração, tanto \ne ;\nsão os mesmos
Raynos

2
@ Raynos Na verdade, eu descobri que o JSLint tende a ser um pouco inútil com a complexidade de alguns códigos pesados ​​de framework com os quais frequentemente trabalho. Além disso,; \ ne \ n não são os mesmos em todas as circunstâncias , caso contrário, nunca haveria a necessidade do;.
Ed James

7
O jslint é inútil, mas o jshint é uma ferramenta diferente.
Raynos 29/03/12

0

Não os deixo de fora, mas altero as regras quando inseri-los.

As regras que a maioria das pessoas usa é

  • Antes de cada linha terminar
  • Exceto que a linha termina com uma }declaração de função
  • Mas apenas uma declaração de função, não atribuição a uma literal de função

Minha regra é: No início de cada linha, iniciando com uma chave / suporte de abertura.

O meu é mais simples, portanto mais fácil de seguir e menos propenso a erros. Além disso, o baixo número de ponto-e-vírgula facilita a localização de erros, deixando-o de fora.


Outro argumento é que o return\nvaluebug infame vem do desconhecimento da ASI. Minha regra obriga você a conhecer o ASI; portanto, é menos provável que as pessoas que usam minha regra caiam na armadilha desse bug.


0

Contagem de bytes. Veja bem, pessoas mal-intencionadas geralmente tentam se encaixar muito em uma única linha de código. Tecnicamente falando, isso não seria possível sem ponto e vírgula. Minha suposição é que é mais uma medida de segurança do que apenas um requisito programático. De alguma forma, isso reduziria significativamente o XSS quando se tornar um requisito e não uma sugestão.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.