Perché il recente passaggio alla rimozione / omissione di punti e virgola da Javascript?


80

Recentemente sembra di moda omettere i punti e virgola da Javascript. Qualche anno fa è stato pubblicato un post sul blog che sottolineava che in Javascript i punti e virgola sono facoltativi e l'essenza del post sembrava essere che non dovresti preoccuparti di loro perché non sono necessari. Il post, ampiamente citato, non fornisce ragioni convincenti per non usarli, solo che lasciarli fuori ha pochi effetti collaterali.

Perfino GitHub è saltato sul carrozzone senza punto e virgola, richiedendo la loro omissione in qualsiasi codice sviluppato internamente, e un recente commit nel progetto zepto.js da parte del suo manutentore ha rimosso tutti i punti e virgola dalla base di codice. Le sue principali giustificazioni erano:

  • è una questione di preferenza per la sua squadra;
  • meno battitura a macchina

Ci sono altri buoni motivi per lasciarli fuori?

Francamente non vedo alcun motivo per ometterli, e certamente nessun motivo per tornare indietro sul codice per cancellarli. Va anche contro ( anni di ) pratica raccomandata , per la quale non compro realmente l'argomento "cult cult". Quindi, perché tutto il recente punto e virgola odio? C'è una carenza che incombe? O è solo l'ultima moda Javascript?


2
"anni di pratica raccomandata" fanno riferimento a una domanda di tag di sondaggi SO inseriti nella lista nera che probabilmente rende autorevole sostenere qualsiasi tipo di opinione
moscerino del

24
@gnat solo perché le persone odiano la domanda su SO non la rende una fonte meno valida di opinione delle persone.
Ryathal,

3
@gnat Le domande "ufficialmente considerate inadeguate su StackOverflow" sono talvolta considerate molto autorevoli dalla comunità di esperti. Triste ma vero.
MarkJ

4
@gnat La domanda nella lista nera in realtà ha alcuni esempi molto interessanti del perché l'omissione di ;può rompere il codice. Quindi direi che è un riferimento utile per questa domanda.
Andres F.

1
Ciò potrebbe essere correlato alla crescente importanza degli hipster nei primi anni del 2010.
Alex

Risposte:


62

Suppongo che la mia ragione sia la più pessima: programma in troppe lingue diverse contemporaneamente (Java, Javascript, PHP) - che richiedono ';' così piuttosto che allenare le dita e gli occhi che il ';' non è necessario per javascript, aggiungo sempre sempre ';'

L'altro motivo è la documentazione: aggiungendo ';' Sto dichiarando esplicitamente a me stesso dove mi aspetto che la dichiarazione finisca. Poi di nuovo uso sempre {}.

L'intero argomento del conteggio dei byte lo trovo irritante e inutile:

1) per librerie comuni come jquery: usa google CDN e probabilmente la libreria sarà già nella cache del browser

2) versione le tue librerie e impostale per essere memorizzate nella cache per sempre.

3) gzip e minimizzare se davvero, davvero necessario.

Ma davvero quanti siti hanno come maggiore velocità il collo di bottiglia rispetto alla velocità di download del loro javascript? Se lavori per uno dei primi 100 siti come Twitter, Google, Yahoo, ecc. Forse. Il resto di noi dovrebbe preoccuparsi solo della qualità del codice e non delle guerre di punto e virgola.


3
Immagino che anche il contrario potrebbe essere vero. Man mano che Python diventa più popolare per il Web, è più facile avere il tuo JS simile a Python.
Ben DeMott,

4
Prova, ma poi gli stessi guerrieri byte mi avrebbero inseguito per gli spazi bianchi non necessari all'inizio delle righe. (Avrei anche i bug di Javascript perché farei affidamento sulla regola del rientro di Python piuttosto che sull'uso di {}
Pat

6
Se ridurre il numero di byte è importante, avrai qualcosa che minimizza i file il più possibile. Se non vale ancora la pena utilizzare un minimizer, non vale la pena preoccuparsi di rimuovere ';' per salvare sul conteggio dei byte.
Lawtonfogle,

3
il conteggio dei byte non è in realtà necessariamente ridotto, in realtà può effettivamente essere aumentato in quanto una nuova riga è spesso (non sempre) in realtà due caratteri (nuova riga seguita da ritorno a capo), quindi nella sua forma più efficiente di spazio il nuovo riga sarà una volta carattere uguale a un punto e virgola di un carattere (se compatti tutto il codice JS in una riga che viene spesso eseguita per il codice JS distribuito, non per il codice sorgente di sviluppo).
ALXGTV,

Gli umani hanno bisogno di rientri per comprendere l'annidamento profondo, che richiede più byte che punti e virgola. I punti e virgola, tuttavia, distraggono gli sprechi dei tasti premuti.
Cees Timmerman,

39

Rende il concatenamento dei metodi più semplice e rende le differenze più pulite

Quindi diciamo che sto jQuerying e ho

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

Se voglio aggiungere elementi e mantenere piccolo il mio commit basato sulla linea , devo aggiungerlo sopra attr. Quindi è un pensiero più lungo di un semplice "aggiungi alla fine". E chi vuole pensare? =)

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

Ma quando lascio cadere i punti e virgola, posso semplicemente aggiungere e chiamarlo un giorno

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

Inoltre, se decido di annullare l'ultimo metodo, non devo riassegnare il punto e virgola e inquinare nuovamente il mio commit.

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

Contro l'Uggo

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

37
Questo è un caso d'uso di nicchia IMO.
JBR Wilkinson,

9
Ma comunque interessante.
Jonathan,

8
Puoi avere un punto e virgola alla fine su una nuova riga rientrata come linea di partenza. Quindi copia e riordina le cose come desideri. Anche questo chiude bene la catena.
Nux,

11
Sono solo io che mi chiedo perché a qualcuno dovrebbe importare quanto siano carini i diff dei loro impegni? come regola generale, le persone leggono il codice, non le differenze.
Jules,

11
@Jules, le differenze più pulite indicano che le fusioni hanno maggiori probabilità di successo.
Joeytwiddle,

22

i punti e virgola in JavaScript sono opzionali

La mia ragione personale per non usare i punti e virgola è il DOC.

Quando uso i punti e virgola, ne dimentico il 2% e devo controllarli / aggiungerli continuamente.

Quando non uso i punti e virgola, non ne inserisco mai uno accidentalmente, quindi non devo mai controllarli / rimuoverli.


3
Buona Sono stato masterizzato da una o due righe senza punto e virgola in un file con il punto e virgola altrimenti corretto.
Jonathan,

3
Esistono parser (ad es. GeSHi) che non analizzeranno correttamente il codice se non sono presenti punti e virgola. Potresti dire che gli umani non commetteranno tali errori ... Ma seriamente - evento se tutta la tua squadra riuscirà a ricordare dove devono essere posizionati i punti e virgola, pensi davvero che lo ricorderanno senza caffè del mattino? E codificheranno in molti stati mentali. Sii sicuro.
Nux,

16

Di recente ho scritto un parser / analizzatore per JavaScript, dove ho dovuto implementare scrupolosamente l'ASI, e ho anche la mia copia del JavaScript di Crockford : The Good Parts sulla mia libreria, che sostiene sempre di utilizzare i punti e virgola. L'intenzione era buona, ma non sempre aiuta nella pratica.

Ovviamente, le persone che scrivono framework come jQuery, zepto, ecc. Sono maestri di sintassi JavaScript e quindi conoscono la differenza tra:

return
{
    status: true
};

e

return {
    status: true
};

JavaScript, sebbene potente, è anche una lingua per principianti e buona fortuna a spiegarlo a qualcuno che sta imparando cos'è un forloop. Come introdurre la maggior parte delle persone a una nuova abilità, ci sono alcune cose più complesse che non vuoi spiegare subito, quindi invece scegli di infondere una credenza da "cult del carico" in certe cose solo per farle decollare. Quindi, hai due scelte quando insegni a un principiante come scrivere JavaScript:

  1. Dì loro "segui questa regola e non chiedere perché", dicendo loro di mettere sempre un punto e virgola alla fine di ogni riga. Sfortunatamente, questo non aiuta nell'esempio sopra, o in qualsiasi altro esempio in cui l'ASI si mette di mezzo. E il programmatore per principianti Mr. o Ms. viene confuso quando il codice sopra non riesce.
  2. Dì loro "segui queste due regole e non chiedere perché", dicendo loro di non preoccuparsi dei punti e virgola alla fine di ogni riga e invece di sempre a) Segui returncon a {e b) Quando una riga inizia con a (, anteponi con a ;.

La scelta dell'opzione 2 è una serie migliore di regole da seguire per il "culto delle merci" (comporterà pochissimi bug relativi all'ASI) e anche se si ottiene una profonda comprensione dell'argomento, sullo schermo sono presenti meno caratteri non necessari.


8
Va bene, ti mordo. Aiutami a capire la differenza di sintassi tra i due esempi sopra. Il mio occhio non allenato vede solo una differenza nella formattazione.
Jesse C. Slicer,

9
O, d'altra parte, mi sono imbattuto nella risposta per puro incidente. Nel primo esempio, il returnè considerato un'istruzione solitaria e il fine riga è l'equivalente di un punto e virgola. Il secondo esempio restituisce effettivamente l'oggetto. Furbata.
Jesse C. Slicer,

9
Non credo di essere d'accordo con l'idea che JavaScript sia una lingua per principianti, ci sono tonnellate di incongruenze ed effetti a sorpresa in JavaScript che non hanno spiegazioni semplici. IMO una lingua per principianti non sarebbe così, chiamerei JavaScript una lingua intermedia.
Ryathal,

2
@Ryathal Capisco a cosa stai arrivando, ma chiamarlo una lingua intermedia mi fa chiedermi quali lingue si intersechi. Lo fai sembrare come se fosse un passo in un viaggio verso qualcos'altro piuttosto che una destinazione a sé stante.
Racheet,

9
Punto di chiarimento: l' returnesempio è in realtà un'eccezione al normale comportamento JS che è quello di tentare di mettere insieme le linee quando viene omesso un punto e virgola. return, breake continuetutti mostrano questo comportamento eccezionale in cui una nuova riga finale viene sempre interpretata come una fine dell'affermazione. (La fonte è "JavaScript: The Definitive Guide" di Flanagan pp25-26). Personalmente, mi sforzo per l'idea di "codice di minima sorpresa". Lasciare i punti e virgola tende a suscitare più sorprese di ogni altra cosa (in genere tengo anche le parentesi graffe anche per affermazioni semplici).
Kyle

16

Non esiste un sovraccarico di informazioni, solo un cattivo design.

- Edward Tufte

È una regola generale nella progettazione grafica escludere elementi e ornamenti non necessari per ridurre il rumore.

Meno elementi visivi sullo schermo significano meno lavoro per il nostro cervello per analizzare le informazioni utili effettive.

let foo = 1

vs.

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

Un esempio esagerato ovviamente, ma illustra il principio generale: ulteriori elementi visivi dovrebbero essere aggiunti se e solo se servono a uno scopo. Quindi, i punti e virgola hanno uno scopo?

I motivi storici per utilizzare i punti e virgola in JavaScript erano:

  • Mantenere la somiglianza con C / Java
  • Evita i problemi di compatibilità con browser e strumenti scritti male
  • Aiutare persone e macchine a rilevare errori di codice
  • L'inserimento automatico del punto e virgola comporta una penalità di prestazione

I problemi di compatibilità sono praticamente un non-problema oggi. I linter moderni possono rilevare anche eventuali errori di codice senza punti e virgola. La somiglianza con C / Java / PHP può ancora essere considerata (vedi la risposta accettata da Pat), ma solo perché altre lingue contengono elementi di sintassi superflui non significa che dovremmo tenerli in JavaScript, soprattutto perché molte altre lingue (Coffeescript, Python, Ruby, Scala, Lua) non li richiedono.

Ho fatto un rapido test per vedere se ci fosse una penalità di prestazione nel V8. Questo è Io.js che analizza un file JavaScript da 41 MB (Lodash ripetuto 100 volte) con punti e virgola e quindi con punti e virgola rimossi:

$ 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

Ognuno deve decidere il proprio stile di codifica preferito per i propri progetti, ma non vedo più alcun beneficio tangibile nell'uso dei punti e virgola, quindi per ridurre il rumore visivo, mi sono fermato.


Vorrei contrastare questo argomento di tralasciare elementi non necessari nel carico che la mente deve fare ora per aggiungere nuovamente nella sintassi opzionale. Ora il punto e virgola non è un'enorme tensione mentale se omesso. Questo è un problema che ho riscontrato con Ruby e Scala. Quando diventa una catena di chiamate con chiamate all'interno delle chiamate, e tutti hanno omesso ogni paren, è un onere separarsi.
Seamus,

8

La scelta di una convenzione di programmazione equivale effettivamente alla scelta di un sottoinsieme della lingua di destinazione. Lo facciamo tutti per i soliti motivi: leggibilità del codice, manutenibilità, stabilità, portabilità, ecc., Sacrificando potenzialmente la flessibilità. Queste ragioni sono vere ragioni commerciali.

Ragioni come "il salvataggio delle sequenze di tasti" e "i programmatori dovrebbero apprendere le regole JavaScript" sono motivi commerciali marginali, quindi hanno poco peso pratico.

Nel mio caso avevo bisogno di accelerare JavaScript molto velocemente, quindi sfruttare un sottoinsieme limitato della lingua era a mio vantaggio. Quindi ho scelto il sottoinsieme JSLint di JavaScript, ho attivato le app Rockstar JSLinter in Eclipse alle impostazioni più restrittive che potessi sopportare e non ho guardato indietro.

Sono grato di essere in grado di evitare i dettagli della differenza tra "==" e "===", o i dettagli dell'inserimento del punto e virgola, perché ho già un elenco di attività alto un miglio e quei dettagli non lo faranno aiutare a fare quei lavori un secondo prima.

Naturalmente la cosa più importante di una convenzione è la coerenza, e pensarla come un sottoinsieme linguistico aiuta a rafforzare questo imperativo. E sebbene ciò possa non aiutare a rispondere alla domanda del PO, penso che potrebbe essere d'aiuto con la sua definizione pratica.


5

Piuttosto una vecchia domanda, tuttavia sono sorpreso che nessuno abbia menzionato:

Minificazione: se ti capita di minimizzare uno snippet JavaScript che non termina esplicitamente le dichiarazioni con un carattere punto e virgola, potresti finire per avere difficoltà a capire cosa c'è che non va in uno snippet che stava funzionando prima della minificazione e ora non funziona.

Ambiguità: i punti e virgola sono opzionali, veri, tuttavia eliminandoli dal codice sorgente, è possibile lasciare al parser alcuni scenari ambigui per decidere autonomamente. Se stai scrivendo 100 righe di codice per un negozio online, sì, forse non importa, ma compiti più seri richiederebbero una chiarezza del 100%.

Molto tempo fa ho letto una bella analogia su qualcos'altro, ma è anche vero in questo caso: (Nel nostro caso) Eliminare i punti e virgola è come attraversare a una luce rossa. Potresti andare bene alla fine o potresti essere colpito da un camion.

Perché sta diventando più popolare in questi giorni?

Personalmente credo che avere JavaScript eseguito sul lato server abbia avuto molti effetti sulla stessa comunità JavaScript. Nel nostro caso, ovviamente nessuno minimizzerà il JavaScript sul lato server (poiché il codice sorgente non dovrebbe essere spedito al browser web del client), quindi non avere punti e virgola sembra molto più sicuro, il che è vero; tuttavia gli altri sviluppatori che imparano da questi libri, articoli e video, purtroppo respingono il fatto che JavaScript sul lato server non è esattamente uguale a JavaScript sul lato client.


I minificatori possono uscire da una nuova riga di un carattere o inserire punti e virgola quando i punti e virgola non sono presenti senza penalità di dimensione. Non so quali (se presenti) minificatori lo fanno. Il pericolo esiste ancora in almeno alcuni di essi, quindi il tuo punto è ancora valido.
uscita il

3

Ci sono buoni motivi per tenerli dentro.

Non sono davvero opzionali, JS può aggiungerli di nuovo con l'inserimento automatico di punti e virgola quando mancano, ma non è la stessa cosa.

JavaScript di Douglas Crockford: The Good Parts afferma in due diverse occasioni che è una cattiva idea. L'inserimento automatico del punto e virgola può nascondere bug nel programma e creare ambiguità.

JSLint non approva.


3

JavaScript non ha bisogno di punti e virgola per terminare le dichiarazioni in oltre un decennio. Questo perché i caratteri newline sono considerati terminatori di istruzioni (credo che questo sia menzionato anche nelle prime specifiche di ECMAScript). Ha davvero molto senso, soprattutto perché non c'è davvero alcuna buona ragione [che io sappia] perché JavaScript abbia bisogno di un uso frequente di punti e virgola ma non di altri linguaggi dichiarativi interpretati come Ruby o Python.

La richiesta di punti e virgola può rendere più semplice la scrittura di un parser per una lingua, ma se ogni interprete là fuori supporta l'omissione dei punti e virgola, qual è esattamente il punto?

Ciò che si riduce è quanto un programmatore sia ben informato: se sai che puoi omettere un punto e virgola, sentiti libero di farlo comprendendo che potrebbe esserci o meno una conseguenza. Gli esseri umani sono macchine decisionali e quasi tutte le decisioni richiedono un compromesso o un compromesso. Il compromesso con il semplice lancio di punti e virgola in tutto il codice (anche nei luoghi in cui non sono necessari) è che il codice diventa meno leggibile (a seconda di chi chiedi) e JSLint non si lamenterà (chi se ne frega ). D'altra parte, il compromesso per omettere i punti e virgola è il fatto che il 90% dei programmatori JavaScript ti castigherà per questo, ma potresti finire per divertirti a scrivere JavaScript di più a causa di ciò.

Cosa ti suona meglio; prendere decisioni informate o prendere decisioni cieche / mentalità da gregge?


Sarei interessato a sapere perché questo ha ricevuto i voti negativi. JavaScript non ha bisogno di punti e virgola per terminare le dichiarazioni; può certamente usarli, ma non sono affatto un requisito. Se fossero necessari, le spiegazioni di nessun altro funzionerebbero. Il fatto (sì, un dato di fatto) che è possibile scrivere un'intera applicazione JavaScript con pochi o nessun punto e virgola lo dimostra. Oltre a ciò, non vedo come capire come funziona uno strumento e usare il proprio ragionamento per prendere decisioni sia in qualche modo discutibile in contrasto con "semplicemente farlo". Questo è ciò che è noto come religione.
Ravenstine,

Non ho votato in negativo, ma il problema potrebbe essere che ciò non è corretto come scritto. I newline non sono considerati terminatori di istruzioni in javascript. È possibile interrompere il punto e virgola a causa di una funzione chiamata inserimento automatico del punto e virgola che consente di correggere automaticamente gli errori di analisi in determinate circostanze. Le persone che sostengono i punti e virgola sostengono che molti programmatori javascript sembrano comprendere male questa regola. Il tuo post sembra essere un argomento a loro favore in questa luce. (In tutta onestà, concordo principalmente con la tua tesi, ma per diversi motivi)
Tim Seguine,

@TimSeguine Sì, l'ho scritto prima di capire meglio. Continuo a non pensare che sia oggettivamente sbagliato non usare il punto e virgola fintanto che le persone lo capiscono esattamente cosa stanno facendo. Dovrei rielaborare il mio post o forse liberarmene dal momento che altri sono intervenuti su questo. Grazie per le educate critiche! :)
Ravenstine,

2

Ho due teorie:

UN)

La cosa su questa scelta è che nel passato, quando erano applicabili JSLint ecc., Stavi scegliendo di dedicare molto tempo a rilevare oscuri errori di sintassi o un ragionevole periodo di tempo per applicare una politica standard sul codice.

Tuttavia, man mano che ci spostiamo maggiormente verso il codice guidato da Unit Test e l'integrazione continua, il tempo (e l'interazione umana) necessario per rilevare un errore di sintassi è diminuito in modo massiccio. Il feedback dei test indicherà rapidamente se il codice funziona come previsto, ben prima che si avvicini a un utente finale, quindi perché perdere tempo ad aggiungere verbosità opzionale?

B)

I programmatori pigri faranno di tutto per semplificare la propria vita a breve termine. Meno battitura a macchina -> meno sforzo -> più facile. (inoltre, non dover utilizzare il punto e virgola eviterà di sforzare l'anulare destro, evitando un po 'di RSI).

(NB Non sono d'accordo con l'idea di omettere qualcosa che chiarisca una dichiarazione).


1
jshint è ancora uno strumento importante.
Raynos,

Per quanto riguarda l'ambiguità di un'affermazione, entrambi \ne ;\nsono gli stessi
Raynos,

2
@Raynos In realtà, ho scoperto che JSLint tende ad essere un po 'inutile con la complessità di alcuni dei codici pesanti del framework con cui lavoro spesso. Inoltre, \ n e \ n non sono gli stessi in tutte le circostanze , altrimenti non ci sarebbe mai bisogno del;.
Ed James,

7
jslint è inutile, tuttavia jshint è uno strumento diverso.
Raynos,

0

Non li tralascio, ma cambio le regole quando inserirli.

Le regole che usano la maggior parte delle persone

  • Prima della fine di ogni riga
  • Tranne che la riga termina con un }proveniente da un'istruzione di funzione
  • Ma solo un'istruzione di funzione, non un'assegnazione a una funzione letterale

La mia regola è: all'inizio di ogni singola riga che inizia con una parentesi graffa / parentesi aperta.

Il mio è più semplice, quindi più facile da seguire e meno soggetto a bug. Inoltre, il basso numero di punti e virgola rende facile la ricerca di bug creati lasciandolo fuori.


Un altro argomento è che il famigerato return\nvaluebug deriva dal non conoscere l'ASI. La mia regola ti obbliga a conoscere l'ASI, quindi le persone che usano la mia regola hanno meno probabilità di cadere nella trappola di quel bug.


0

Conteggio byte. Vedete, le persone maligne di solito cercano di inserirsi così tanto in una singola riga di codice. Tecnicamente parlando, ciò non sarebbe possibile senza punti e virgola. La mia supposizione è che si tratti più di una misura di sicurezza che di un semplice requisito programmatico. In qualche modo, ciò ridurrebbe significativamente l'XSS quando diventa un requisito piuttosto che un suggerimento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.