Le parentesi graffe sono necessarie nelle istruzioni di una riga in JavaScript?


163

Una volta ho sentito che lasciare JavaScript tra parentesi graffe potrebbe essere dannoso in JavaScript. Non ricordo più il ragionamento e una ricerca su Google non ha aiutato molto.

C'è qualcosa che rende una buona idea circondare tutte le affermazioni tra parentesi graffe in JavaScript?

Lo sto chiedendo, perché tutti sembrano farlo.


5
Nota: solo la prima istruzione sta assumendo l'ambito, anche se si hanno più istruzioni su una riga, quindi non si tratta di "istruzioni di una riga" ma piuttosto di un'unica istruzione
Kris Ivanov,

1
Potresti pensare al problema descritto in questa risposta
Blorgbeard esce il

@Blorgbeard: no, in realtà ho risposto a quella risposta tempo fa.
Torre

Ah, così vedo.
Poco male

Risposte:


204

No

Ma sono raccomandati. Se mai espandi l'affermazione ne avrai bisogno.

Questo è perfettamente valido

if (cond) 
    alert("Condition met!")
else
    alert("Condition not met!")

Tuttavia, si consiglia vivamente di utilizzare sempre le parentesi graffe perché se tu (o qualcun altro) espandi mai la dichiarazione, sarà richiesta.

Questa stessa pratica segue in tutti i linguaggi di stile della sintassi C con controvento. C, C ++, Java, persino PHP supportano tutti un'istruzione di riga senza parentesi graffe. Devi capire che stai salvando solo due personaggi e con gli stili di rinforzo di alcune persone non stai nemmeno salvando una linea. Preferisco uno stile completo (come segue), quindi tende ad essere un po 'più lungo. Il compromesso si incontra molto bene con il fatto che hai una leggibilità del codice estremamente chiara.

if (cond) 
{
    alert("Condition met!")
}
else
{
    alert("Condition not met!")
}

28
+1, risposta informativa. Personalmente, non ho mai trovato utile fare questa cosa "raccomandata". Non ho mai codificato Python, quindi non inserisco solo le cose e mi aspetto che il rientro abbia importanza. Se aggiungo una dichiarazione, aggiungo anche parentesi graffe. Sempre. Non ricordo una sola volta che mi ha morso. Non in C, non in C # non in JavaScript.
Jakob,

16
@Kirk: Douglas Crockford lo raccomanda. Concordo sul fatto che si tratta di una decisione personale soggettiva, ma quando si lavora in gruppo è più semplice digitare semplicemente le parentesi graffe.
Josh K,

10
@Josh, oh, bene lo ha detto Crockford. Questa deve essere l'ultima parola. ;) (sto solo scherzando) Il problema è che la soggettività di questo punto si estende a tutti i linguaggi simili a C, e si possono trovare opinioni forti (per entrambe le posizioni).
Kirk Woll,

11
La mia esperienza personale dimostra che non posizionare i braccialetti può portare a grossi problemi quando si lavora in gruppo.
Signori il

4
È buona norma utilizzare sempre le parentesi graffe {}. Come ha detto @Arx, c'è molto più spazio per l'errore se li lasci fuori. Apple ha persino avuto un bug in SSL / TLS di iOS perché non utilizzava le parentesi graffe
Keenan Lidral-Porter

94

C'è un aspetto di leggibilità - in quanto quando si hanno istruzioni composte può diventare molto confuso. Il rientro aiuta ma non significa nulla per il compilatore / interprete.

var a;
var b;
var c;

//Indenting is clear
if (a===true)
  alert(a); //Only on IF
alert(b); //Always

//Indenting is bad
if (a===true)
  alert(a); //Only on IF
  alert(b); //Always but expected?

//Nested indenting is clear
if (a===true)
  if (b===true)
    alert(a); //Only on if-if
alert (b); //Always

//Nested indenting is misleading
if (a===true)
  if (b===true)
    alert(a); //Only on if-if
  alert (b); //Always but expected as part of first if?

//Compound line is misleading
//b will always alert, but suggests it's part of if
if (a===true) alert(a);alert(b); 
else alert(c); //Error, else isn't attached

E poi c'è un aspetto di estensibilità:

//Problematic
if (a===true)
  alert(a);
  alert(b); //We're assuming this will happen with the if but it'll happen always
else       //This else is not connected to an if anymore - error
  alert(c);

//Obvious
if (a===true) {
  alert(a); //on if
  alert(b); //on if
} else {
  alert(c); //on !if
} 

L'idea è che se hai sempre le parentesi quadre sai di inserire altre istruzioni all'interno di quel blocco.


4
Ecco perché dovremmo sempre usarlo come one-liner: if (a===true) alert(a);. Adesso è chiaro!
João Pimentel Ferreira,

1
L'uso della parentesi graffa sinistra e della parentesi graffa destra chiarisce i condizionali. Per i sognatori tra noi, indicato anche come l'uccello volante destro e sinistro.
HalfMens

61

La domanda pone delle dichiarazioni su una riga. Tuttavia, i numerosi esempi forniti mostrano ragioni per non tralasciare le parentesi graffe basate su più righe. È assolutamente sicuro non usare parentesi su una riga, se quello è lo stile di codifica che preferisci.

Ad esempio, la domanda chiede se questo è ok:

 if (condition) statement;

Non chiede se va bene:

 if (condition)
   statement;

Penso che lasciare le parentesi fuori sia preferibile perché rende il codice più leggibile con una sintassi meno superflua.

Il mio stile di codifica è di non usare mai parentesi a meno che il codice non sia un blocco. E non usare mai più istruzioni su una sola riga (separate da punti e virgola). Trovo che sia facile da leggere e da chiarire e che non abbia mai problemi di scoping sulle dichiarazioni "if". Di conseguenza, l'utilizzo di parentesi su una singola istruzione condition richiederebbe 3 righe. Come questo:

 if (condition) {
   statement;
 }

Utilizzare una riga se l'istruzione è preferibile perché utilizza meno spazio verticale e il codice è più compatto.

Non costringerei altri ad usare questo metodo, ma funziona per me e non potrei essere più in disaccordo con gli esempi forniti su come tralasciare le parentesi porta a errori di codifica / scoping.


1
Ho sempre pensato che uno dovrebbe sempre includere parentesi graffe ... ma sto ripensando ora. Hai la guida di stile airbnb dalla tua parte!
Senderle,

1
Eppure dimentichi che la maggior parte dei formattatori di codice lo cambia in un formato a 2 righe e sei tornato al codice problematico. L'argomento dello spazio verticale è semplicemente stupido. La leggibilità vince sempre e gli schermi di oggi sono enormi.
Kim,

1
Le 2 righe aggiunte per ogni parentesi, per racchiudere le dichiarazioni di una riga non sono un costo elevato rispetto a un potenziale danno che può essere causato da uno sviluppatore - anche molto attento - a mantenere il codice. Tu stesso puoi essere un grande sviluppatore con abilità mitiche, ma non puoi presumere che lo siano i tuoi colleghi. BACIO, avvolgi le cose in un contesto e rendilo il più semplice possibile per gli altri o finirai per finire nei guai.
Maciej Tokarz,

@senderle La regola eslint per controllare questo può essere trovata qui: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
silkfire

15

Tecnicamente no ma per il resto assolutamente Sì !!!

Dimentica "È la preferenza personale", "il codice funzionerà perfettamente", "ha funzionato bene per me", "è più leggibile" yada yada BS. Questo potrebbe facilmente portare a problemi molto seri se commetti un errore e credimi, è molto facile commettere un errore durante la codifica (Non credere ?, dai un'occhiata al famoso Apple andare a fallire bug ).

Argomento: "È preferenza personale"

No non lo è. A meno che tu non sia una squadra di un solo uomo che parte su Marte, no. La maggior parte delle volte ci saranno altre persone a leggere / modificare il codice. In qualsiasi serio team di codifica questo sarà il modo raccomandato, quindi non è una "preferenza personale".

Argomento: "il codice funzionerà perfettamente"

Così fa il codice spaghetti! Significa che va bene crearlo?

Argomento: "ha funzionato bene per me"

Nella mia carriera ho visto tanti bug creati a causa di questo problema. Probabilmente non ricordi quante volte hai commentato 'DoSomething()'e sconcertato dal perché 'SomethingElse()'si chiama:

if (condition) 
    DoSomething();
SomethingElse();

O aggiunto "SomethingMore" e non si è accorto che non verrà chiamato (anche se il rientro implica altrimenti):

if (condition)
  DoSomething();
  SomethingMore();

Ecco un esempio di vita reale che ho avuto. Qualcuno voleva disattivare tutta la registrazione in modo da eseguire find & replace "console.log"=> //"console.log":

if (condition) 
   console.log("something");
SomethingElse();

Vedi il problema?

Anche se pensi "questi sono così banali, non lo farei mai"; ricorda che ci sarà sempre un membro del team con capacità di programmazione inferiori a te (si spera che tu non sia il peggiore del team!)

Argomento: "è più leggibile"

Se ho imparato qualcosa sulla programmazione, è che le cose semplici diventano molto complesse molto rapidamente. È molto comune che questo:

if (condition) 
    DoSomething();

diventa quanto segue dopo che è stato testato con diversi browser / ambienti / casi d'uso o aggiunte nuove funzionalità:

if (a != null)
   if (condition) 
      DoSomething();
   else
      DoSomethingElse(); 
      DoSomethingMore();
else 
    if (b == null)
         alert("error b");
    else 
         alert("error a");

E confrontalo con questo:

 if (a != null) {
    if (condition) { 
       DoSomething();
    }
    else {
       DoSomethingElse();
       DoSomethingMore();
    }
 } else if (b == null) {
    alert("error b");
 } else {
    alert("error a");
 }

PS: i punti bonus vanno a chi ha notato il bug nell'esempio sopra.


2
bene il bug ovvio è DoSomethingMore (); Ma c'è anche un altro bug. se a è null eb è null, si ottiene solo "errore b", non si ottiene mai "errore a".
rocketsarefast,

Con i tuoi esempi, il tuo team di sviluppo non sa affatto come programmare, le parentesi graffe non li aiuteranno ...
Carlos ABS

alcuni esempi provengono dal team di sviluppatori Apple
Caner,

13

Non ci sono problemi di manutenibilità!

Il problema con tutti voi è che metti punti e virgola ovunque. Non hai bisogno di parentesi graffe per più dichiarazioni. Se vuoi aggiungere una dichiarazione, usa solo le virgole.

if (a > 1)
 alert("foo"),
 alert("bar"),
 alert("lorem"),
 alert("ipsum");
else
 alert("blah");

Questo è un codice valido che verrà eseguito come previsto!


2
Non si intende if, elsee alertnon If, Elsee Alert?
Anish Gupta,

Caspita, non lo sapevo, grazie per avermi informato! Sembra che molte persone tralascino questo importante dettaglio.
Hendeca,

13
Mentre questo funziona in JavaScript, è al di là di me il motivo per cui vorresti mai farlo. Sto provando a indovinare che la maggior parte degli sviluppatori non ne è a conoscenza (me stesso incluso prima di leggere questo), che sospetto diventerebbe rapidamente un problema di manutenibilità tra gli sviluppatori. A volte, il modo più intelligente non è il migliore.
Simone,

14
Questo è orribile. Se qualcuno aggiunge un'istruzione e si dimentica di trasformare il punto e virgola in una virgola sull'ultima ora nel blocco, hai un bug che può essere davvero difficile da individuare perché anche la virgola e il punto e virgola alla fine della riga sembrano simile.
Ingo Bürk,

1
Preferisco un approccio "Hemingwayian" : molto pulito. E senza spazio tra ife (, comeif(true) doSomething();
victorf

8

Non esiste alcun motivo di programmazione per utilizzare le parentesi graffe su una riga.

Questo dipende solo dalle preferenze e dalla leggibilità dei programmatori.

Il tuo codice non si romperà a causa sua.


7

Oltre al motivo menzionato da @Josh K (che si applica anche a Java, C ecc.), Un problema speciale in JavaScript è l'inserimento automatico del punto e virgola . Dall'esempio di Wikipedia:

return
a + b;

// Returns undefined. Treated as:
//   return;
//   a + b;

Quindi, questo può anche produrre risultati imprevisti, se usato in questo modo:

if (x)
   return
   a + b;

Non è molto meglio scrivere

if (x) {
   return
   a + b;
}

ma forse qui l'errore è un po 'più facile da rilevare (?)


Tutti questi esempi mi sembrano orribili, a meno che gli autori non siano temporanei e pagati per riga o fino a quando non funziona.
Cees Timmerman,


4

Ci sono molte buone risposte, quindi non ripeterò, tranne per dire la mia "regola" quando le parentesi graffe possono essere omesse: a condizioni che "restituiscono" o "lanciano" (ad es.) Come unica affermazione . In questo caso il controllo di flusso è già chiaro che sta terminando:

Anche il "caso negativo" può essere rapidamente identificato (e risolto) a causa del controllo del flusso finale. Questa "regola" di concetto / struttura si applica anche a più lingue.

if (x)
    return y;
    always();

Naturalmente, questo è anche il motivo per cui si potrebbe usare una linter ..


3

Ecco perché è raccomandato

Diciamo che scrivo

if(someVal)
    alert("True");

Quindi arriva il prossimo sviluppatore e dice "Oh, devo fare qualcos'altro", così scrivono

if(someVal)
    alert("True");
    alert("AlsoTrue");

Ora, come puoi vedere, "AlsoTrue" sarà sempre vero, perché il primo sviluppatore non ha utilizzato le parentesi graffe.


Non è corretto, ti manca 'else': if (someVal) alert ("True"); else alert ("AlsoTrue"); sarebbe corretto. Non lo userei perché mi piace {} perché è molto meglio leggibile.
Gerrit B,

1
Eh? Non avevo un'altra affermazione. Stavo dicendo che senza parentesi graffe, può portare a bug se qualcuno aggiunge una nuova linea. Penso che tu non abbia capito il mio punto.
Amir Raminfar,

Penso che quello che sta dicendo sia che la seconda riga verrà eseguita indipendentemente da cosa. Un'istruzione If senza parentesi graffe può eseguire solo 1 riga.
PostCodeism,

3

Attualmente sto lavorando su un minificatore. Anche ora lo controllo su due enormi script. Sperimentalmente ho scoperto: è possibile rimuovere le parentesi graffe dietro per, se, altrimenti, mentre funzione * se le parentesi graffe non includono ';', 'return', 'for', 'if', 'else', 'mentre', 'fare', 'funzione'. Interruzioni di riga non pertinenti.

function a(b){if(c){d}else{e}} //ok  
function a(b){if(c)d;else e}   //ok

Naturalmente è necessario sostituire la parentesi graffa di chiusura con un punto e virgola se non è seguita da un'altra parentesi graffa di chiusura.

Una funzione non deve terminare con una virgola.

var a,b=function()c;  //ok *but not in Chrome
var b=function()c,a;  //error  

Testato su Chrome e FF.


2

L'ho sempre trovato

if(valid) return;

è più facile per me che

if(valid) {
  return;
}

anche condizionato come

(valid) ? ifTrue() : ifFalse();

sono più facili da leggere (la mia opinione personale) piuttosto che

if(valid) {
  ifTrue();
} else {
  ifFalse();
}

ma immagino che dipenda dallo stile di programmazione


2

Non risponde direttamente alla domanda, ma di seguito è riportata una breve sintassi relativa alla condizione if su una riga

Ex:

var i=true;
if(i){
  dosomething();
}

Può essere scritto così:

var i=true;
i && dosomething();


1

Ho trovato questa risposta cercando un'esperienza simile, quindi ho deciso di rispondere con la mia esperienza.

Le istruzioni senza parentesi funzionano nella maggior parte dei browser, tuttavia, ho verificato che i metodi senza parentesi in realtà non funzionano in alcuni browser.

A partire dal 26 febbraio 2018, questa affermazione funziona in Pale Moon, ma non in Google Chrome.

function foo()
   return bar;

0

Il livello di rientro iniziale di un'istruzione deve essere uguale al numero di parentesi graffe aperte sopra di essa. (esclusi parentesi graffe quotate o commentate o quelle nelle direttive del preprocessore)

Altrimenti K&R sarebbe un buon stile di rientro. Per correggere il loro stile, raccomando di inserire brevi istruzioni if ​​semplici su una riga.

if (foo) bar();    // I like this. It's also consistent with Python FWIW

invece di

if (foo)
   bar();   // not so good

Se stavo scrivendo un editor, farei in modo che il suo pulsante di formattazione automatica risucchiasse la barra fino alla stessa riga di pippo, e lo farei inserire parentesi attorno alla barra se premi Invio prima in questo modo:

if (foo) {
  bar();    // better
}

Quindi è facile e coerente aggiungere nuove istruzioni sopra o sotto la barra all'interno del corpo dell'istruzione if

if (foo) {
  bar();    // consistent
  baz();    // easy to read and maintain
}

-1

A volte sembrano essere necessari! Non ci potevo credere, ma ieri mi è venuto in mente una sessione di Firebug (recente Firefox 22.0)

if (! my.condition.key)
    do something;

eseguito eseguire qualcosa nonostante my.condition.key fosse vero . Aggiunta di parentesi graffe:

if (! my.condition.var) {
    do something;
}

risolto il problema. Ci sono miriadi di esempi in cui apparentemente funziona senza le parentesi graffe, ma in questo caso sicuramente non ha funzionato.

Le persone che tendono a mettere più di una frase su una linea dovrebbero sicuramente usare sempre le parentesi graffe, ovviamente, perché cose del genere

if (condition)
    do something; do something else;

sono difficili da trovare.


Sono curioso di sapere in quale scenario la mancanza di parentesi graffe ha reso vera la condizione if, puoi ricordarla o darne un vero esempio?
gitsitgo,

L'espressione condizionale viene sempre valutata prima dell'istruzione. Sono anche molto curioso di vedere un vero esempio di questo perché rappresenterebbe un bug nell'interprete.
Punto

-1

Vorrei solo notare che puoi anche lasciare le parentesi graffe al di fuori dell'altro. Come visto in questo articolo di John Resig .

if(2 == 1){
    if(1 == 2){
        console.log("We will never get here")
    }
} else 
    console.log("We will get here")

Lo [stile parentesi graffe Qt] [1] richiede blocchi su entrambi i lati di una elseper adattarsi all'uso delle parentesi graffe - questo esempio richiederebbe le parentesi graffe sul elseblocco per passare una revisione del codice. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgrease

Perché il downvote? La dichiarazione sopra è accurata al 100%.
Johnston,

-1

C'è un modo per ottenere parentesi graffe a più linee se le istruzioni .. (Wow che inglese ..) ma è un po 'tedius:

if(true)
   funcName();
else
   return null;


function funcName(){
  //Do Stuff Here...
}

Non devi avere così tante nuove linee quando ometti le parentesi graffe. Quanto sopra può anche essere scritto su due righe come: if (true) funcName()e else return null
phobos
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.