Les accolades sont-elles nécessaires dans les instructions sur une ligne en JavaScript?

163

Une fois, j'ai entendu dire que laisser les accolades dans des déclarations sur une ligne pouvait être nuisible en JavaScript. Je ne me souviens plus du raisonnement et une recherche sur Google n'a pas beaucoup aidé.

Y a-t-il quelque chose qui fait que c'est une bonne idée d'entourer toutes les instructions entre accolades en JavaScript?

Je demande, car tout le monde semble le faire.

La tour
la source
5
Remarque: seule la première instruction assume la portée, même si vous avez plusieurs instructions sur une ligne, donc ce ne sont pas des "instructions d'une ligne" mais plutôt une seule déclaration
Kris Ivanov
1
Vous pensez peut-être au problème décrit dans cette réponse
Blorgbeard est sorti le
@Blorgbeard: non, j'ai en fait répondu à cette réponse il y a quelque temps.
Tour du
Hah, donc je vois.
Qu'à cela
Voici votre réponse: medium.com/@jonathanabrams
Erwan Legrand

Réponses:

204

Non

Mais ils sont recommandés. Si jamais vous développez la déclaration, vous en aurez besoin.

C'est parfaitement valable

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

Cependant, il est fortement recommandé de toujours utiliser des accolades, car si vous (ou quelqu'un d'autre) développez un jour l'instruction, elle sera requise.

Cette même pratique s'applique à tous les langages de style syntaxique C avec accolades. C, C ++, Java, même PHP prennent tous en charge une instruction de ligne sans accolades. Vous devez réaliser que vous n'enregistrez que deux caractères et qu'avec les styles de contreventement de certaines personnes, vous n'enregistrez même pas une ligne. Je préfère un style d'accolade complète (comme suit), donc il a tendance à être un peu plus long. Le compromis est très bien réalisé avec le fait que vous avez une lisibilité du code extrêmement claire.

if (cond) 
{
    alert("Condition met!")
}
else
{
    alert("Condition not met!")
}
Josh K
la source
28
+1, réponse informative. Personnellement cependant, je n'ai jamais trouvé utile de faire cette chose "recommandée". Je n'ai jamais codé python, donc je ne me contente pas d'insérer des choses et je m'attends à ce que l'indentation compte. Si j'ajoute une déclaration, j'ajoute également des accolades. Toujours. Je ne me souviens pas une seule fois où ça m'a mordu. Pas en C, pas en C # pas en JavaScript.
Jakob
16
@Kirk: Douglas Crockford le recommande. Je conviens qu'il s'agit d'une décision personnelle subjective, mais lorsque vous travaillez en groupe, il est plus facile de simplement taper les accolades.
Josh K
10
@Josh, oh, eh bien Crockford l'a dit. Cela doit être le dernier mot. ;) (je plaisante) Le problème est que la subjectivité de ce point s'étend à tous les langages de type C, et des opinions fortes peuvent être trouvées partout (pour les deux positions).
Kirk Woll
11
Mon expérience personnelle montre que ne pas placer de brassards peut conduire à de gros problèmes lorsque l'on travaille en équipe.
Messieurs
4
C'est une bonne pratique de toujours utiliser les accolades {}. Comme @Arx l'a dit, il y a beaucoup plus de place pour l'erreur si vous les oubliez. Apple a même eu un bogue dans SSL / TLS d'iOS parce qu'ils n'utilisaient pas d'accolades
Keenan Lidral-Porter
94

Il y a un aspect de lisibilité - en ce que lorsque vous avez des instructions composées, cela peut devenir très déroutant. L'indentation aide mais ne signifie rien pour le compilateur / interpréteur.

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

Et puis il y a un aspect d'extensibilité:

//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
} 

On pense que si vous avez toujours les crochets, vous savez insérer d'autres instructions à l'intérieur de ce bloc.

Rudu
la source
4
Voilà pourquoi nous devons toujours l' utiliser comme une doublure: if (a===true) alert(a);. Maintenant c'est clair!
João Pimentel Ferreira
1
L'utilisation d'un crochet bouclé gauche et d'un crochet bouclé droit rend les conditions claires. Pour les rêveurs parmi nous, également appelé oiseau volant gauche et droit.
HalfMens
61

La question porte sur les déclarations sur une seule ligne. Pourtant, les nombreux exemples fournis montrent des raisons de ne pas omettre les accolades basées sur des instructions sur plusieurs lignes. Il est tout à fait sûr de ne pas utiliser de parenthèses sur une seule ligne, si c'est le style de codage que vous préférez.

Par exemple, la question demande si cela est correct:

 if (condition) statement;

Il ne demande pas si cela est correct:

 if (condition)
   statement;

Je pense qu'il est préférable de laisser les crochets car cela rend le code plus lisible avec une syntaxe moins superflue.

Mon style de codage est de ne jamais utiliser de crochets à moins que le code ne soit un bloc. Et de ne jamais utiliser plusieurs instructions sur une seule ligne (séparées par des points-virgules). Je trouve cela facile à lire et clair et je n'ai jamais de problèmes de portée sur les déclarations «si». Par conséquent, l'utilisation de crochets sur une seule instruction de condition if nécessiterait 3 lignes. Comme ça:

 if (condition) {
   statement;
 }

L'utilisation d'une instruction if sur une ligne est préférable car elle utilise moins d'espace vertical et le code est plus compact.

Je ne forcerais pas les autres à utiliser cette méthode, mais cela fonctionne pour moi et je ne pourrais pas être plus en désaccord avec les exemples fournis sur la façon dont le fait de laisser de côté les crochets conduit à des erreurs de codage / de portée.

peawormsworth
la source
1
J'ai toujours pensé qu'il fallait toujours inclure un appareil dentaire ... mais je repense maintenant. Vous avez le guide de style airbnb de votre côté!
senderle
1
Pourtant, vous oubliez que la plupart des formateurs de code changent cela en un format à 2 lignes et vous êtes de retour au code problématique. L'argument de l'espace vertical est tout simplement idiot. La lisibilité l'emporte toujours et les écrans d'aujourd'hui sont énormes.
Kim
1
Les 2 lignes ajoutées pour chaque support, pour entourer vos instructions d'une ligne ne sont pas un gros coût par rapport aux dommages potentiels qui peuvent être causés par un développeur - même très prudent - qui maintient votre code. Vous-même pouvez être un grand développeur avec des compétences mythiques, mais vous ne pouvez pas supposer que vos collègues le sont. BAISER, emballez les choses avec un contexte et rendez les choses aussi faciles que possible pour les autres ou vous finirez par avoir des ennuis.
Maciej Tokarz
@senderle La règle eslint pour contrôler cela peut être trouvée ici: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
silkfire
15

Techniquement non mais sinon absolument oui !!!

Oubliez "C'est une préférence personnelle", "le code fonctionnera très bien", "il a bien fonctionné pour moi", "c'est plus lisible" yada yada BS. Cela pourrait facilement conduire à des problèmes très graves si vous faites une erreur et croyez-moi, il est très facile de faire une erreur lorsque vous codez (ne croyez pas?, Consultez le célèbre bug Apple go to fail ).

Argument: "C'est une préférence personnelle"

Non, ce n'est pas le cas. À moins que vous ne soyez une équipe d'un seul homme partant sur Mars, non. La plupart du temps, d'autres personnes liront / modifieront votre code. Dans toute équipe de codage sérieuse, ce sera la méthode recommandée, donc ce n'est pas une «préférence personnelle».

Argument: "le code fonctionnera très bien"

Il en va de même pour le code spaghetti! Cela signifie-t-il que vous pouvez le créer?

Argument: "cela a bien fonctionné pour moi"

Dans ma carrière, j'ai vu tellement de bugs créés à cause de ce problème. Vous ne vous souvenez probablement pas combien de fois vous avez commenté 'DoSomething()'et déconcerté par la raison de l' 'SomethingElse()'appel:

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

Ou ajouté 'SomethingMore' et n'a pas remarqué qu'il ne sera pas appelé (même si l'indentation implique le contraire):

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

Voici un exemple concret que j'ai eu. Quelqu'un a voulu désactiver toute la journalisation afin de lancer find & replace "console.log"=> //"console.log":

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

Vous voyez le problème?

Même si vous pensez, "ce sont si insignifiants, je ne ferais jamais cela"; rappelez-vous qu'il y aura toujours un membre de l'équipe avec des compétences en programmation inférieures à vous (j'espère que vous n'êtes pas le pire de l'équipe!)

Argument: "c'est plus lisible"

Si j'ai appris quelque chose sur la programmation, c'est que les choses simples deviennent très vite très complexes. Il est très courant que ceci:

if (condition) 
    DoSomething();

se transforme en ce qui suit après avoir été testé avec différents navigateurs / environnements / cas d'utilisation ou de nouvelles fonctionnalités sont ajoutées:

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

Et comparez-le avec ceci:

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

PS: les points bonus vont à celui qui a remarqué le bogue dans l'exemple ci-dessus.

Caner
la source
2
eh bien, le bogue évident est le DoSomethingMore (); Mais il y a aussi un autre bug. si a est nul et b est nul, vous n'obtiendrez que "erreur b", vous n'obtiendrez jamais "erreur a".
rocketsarefast le
D'après vos exemples, votre équipe de développement ne sait pas du tout coder, les accolades ne les aideront pas ...
Carlos ABS
certains des exemples proviennent de l'équipe de développeurs Apple
Caner
13

Il n'y a aucun problème de maintenabilité!

Le problème avec vous tous est que vous mettez des points-virgules partout. Vous n'avez pas besoin d'accolades pour plusieurs instructions. Si vous souhaitez ajouter une instruction, utilisez simplement des virgules.

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

Ceci est un code valide qui fonctionnera comme prévu!

William Malo
la source
2
Tu ne veux pas dire if, elseet alertet non If, Elseet Alert?
Anish Gupta
Wow, je ne savais pas cela, merci de m'avoir informé! Il semble que la plupart des gens oublient ce détail important.
Hendeca
13
Bien que cela fonctionne en JavaScript, je ne comprends pas pourquoi vous voudriez un jour faire cela. J'imagine que la majorité des développeurs ne sont pas au courant de cela (moi-même inclus avant de lire ceci), ce qui, je suppose, deviendrait rapidement un problème de maintenabilité parmi les développeurs. Parfois, la manière la plus intelligente n'est pas la meilleure.
Simon
14
C'est horrible. Si quelqu'un ajoute une instruction et oublie de transformer le point-virgule en virgule sur l'avant-dernière instruction du bloc, vous avez un bogue qui peut être très difficile à repérer car la virgule et le point-virgule à la fin de la ligne semblent trop similaire.
Ingo Bürk
1
Je préfère une approche "Hemingwayian" : très propre. Et sans espace entre ifet (, commeif(true) doSomething();
victorf
8

Il n'y a aucune raison de programmation d'utiliser les accolades sur les instructions d'une ligne.

Cela ne dépend que des préférences et de la lisibilité des codeurs.

Votre code ne cassera pas à cause de cela.

Yahel
la source
7

En plus de la raison mentionnée par @Josh K (qui s'applique également à Java, C etc.), un problème particulier en JavaScript est l'insertion automatique de points-virgules . De l'exemple de Wikipédia:

return
a + b;

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

Donc, cela peut également donner des résultats inattendus, s'il est utilisé comme ceci:

if (x)
   return
   a + b;

Ce n'est pas vraiment mieux d'écrire

if (x) {
   return
   a + b;
}

mais peut-être qu'ici l'erreur est un peu plus facile à détecter (?)

Chris Lercher
la source
Tous ces exemples me paraissent horribles, à moins que les auteurs ne soient temporaires et payés à la ligne ou jusqu'à ce que cela fonctionne.
Cees Timmerman
6

C'est une question de style, mais les accolades bouclées sont bonnes pour éviter d'éventuelles suspensions .

pault
la source
4

Il y a beaucoup de bonnes réponses, donc je ne vais pas répéter, sauf pour dire ma «règle» quand les accolades peuvent être omises: à des conditions qui «retournent» ou «jettent» (par exemple) comme seule déclaration . Dans ce cas, le contrôle de flux est déjà clair qu'il se termine:

Même le «mauvais cas» peut être rapidement identifié (et corrigé) grâce au contrôle de flux de terminaison. Cette «règle» concept / structure s'applique également à un certain nombre de langues.

if (x)
    return y;
    always();

Bien sûr, c'est aussi pourquoi on peut utiliser un linter.

user2864740
la source
3

Voici pourquoi il est recommandé

Disons que j'écris

if(someVal)
    alert("True");

Puis le développeur suivant arrive et dit "Oh, je dois faire autre chose", alors ils écrivent

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

Maintenant, comme vous pouvez le voir, "AlsoTrue" sera toujours vrai, car le premier développeur n'a pas utilisé d'accolades.

Amir Raminfar
la source
Ce n'est pas correct, il vous manque l'alerte 'else': if (someVal) ("True"); else alert ("AlsoTrue"); serait correct. Je ne l'utiliserais pas parce que j'aime le {} car il est bien mieux lisible.
Gerrit B
1
Hein? Je n'avais pas d'autre déclaration. Je disais que sans accolades, cela peut conduire à des bugs si quelqu'un ajoute une nouvelle ligne. Je pense que vous n'avez pas compris mon point.
Amir Raminfar
Je pense que ce qu'il dit, c'est que la deuxième ligne sera exécutée quoi qu'il arrive. Une instruction If sans accolades ne peut exécuter qu'une seule ligne.
PostCodeism
3

Je travaille actuellement sur un minifier. Même maintenant, je le vérifie sur deux énormes scripts. Expérimentalement, j'ai découvert: vous pouvez supprimer les accolades derrière pour, if, else, while, function * si les accolades n'incluent pas ';', 'return', 'for', 'if', 'else', 'while', 'do', 'function'. Sauts de ligne indépendants.

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

Bien sûr, vous devez remplacer l'accolade fermante par un point-virgule si elle n'est pas suivie par une autre accolade fermante.

Une fonction ne doit pas se terminer par une virgule.

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

Testé sur Chrome et FF.

BF
la source
2

J'ai toujours trouvé ça

if(valid) return;

est plus facile pour mes yeux que

if(valid) {
  return;
}

également conditionnel tel que

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

sont plus faciles à lire (mon opinion personnelle) plutôt que

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

mais je suppose que cela se résume au style de codage

Yogi
la source
2

Ne répond pas directement à la question, mais vous trouverez ci-dessous une courte syntaxe sur la condition if sur une ligne

Ex:

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

Peut être écrit comme ceci:

var i=true;
i && dosomething();
Alee
la source
1

Il existe de nombreux problèmes avec javascript. Jetez un œil à l' architecte JavaScript Douglas Crockford qui en parle. L' instruction if semble convenir mais l' instruction return peut poser un problème.

return
{
    ok:false;
}
//silent error (return undefined)

return{
    ok:true;
}
//works well in javascript
Kamayd
la source
1

J'ai trouvé cette réponse en recherchant une expérience similaire, alors j'ai décidé d'y répondre avec mon expérience.

Les instructions sans parenthèse fonctionnent dans la plupart des navigateurs, cependant, j'ai testé que les méthodes sans parenthèses ne fonctionnent pas dans certains navigateurs.

Depuis le 26 février 2018, cette déclaration fonctionne dans Pale Moon, mais pas dans Google Chrome.

function foo()
   return bar;
Gabriel I.
la source
0

Le niveau d'indentation de début d'une instruction doit être égal au nombre d'accolades ouvertes au-dessus. (à l'exclusion des accolades entre guillemets ou commentés ou dans les directives du préprocesseur)

Sinon, K&R serait un bon style d'indentation. Pour corriger leur style, je recommande de placer de courtes instructions if simples sur une seule ligne.

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

au lieu de

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

Si j'écrivais un éditeur, je ferais en sorte que son bouton de formatage automatique suce la barre jusqu'à la même ligne que foo, et je le ferais insérer des accolades autour de la barre si vous appuyez sur Entrée avant comme ceci:

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

Ensuite, il est facile et cohérent d'ajouter de nouvelles instructions au-dessus ou en dessous de la barre dans le corps de l'instruction if

if (foo) {
  bar();    // consistent
  baz();    // easy to read and maintain
}
Toku
la source
-1

Parfois, ils semblent nécessaires! Je ne pouvais pas le croire moi-même, mais hier, il m'est venu à l'esprit lors d'une session Firebug (récente Firefox 22.0) que

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

exécuté faire quelque chose malgré my.condition.key était vrai . Ajout d'accolades:

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

fixé cette question. Il existe des myriards d'exemples où cela fonctionne apparemment sans les accolades, mais dans ce cas, ce n'est certainement pas le cas.

Les personnes qui ont tendance à mettre plus d'une déclaration sur une ligne devraient très certainement toujours utiliser des accolades, bien sûr, car des choses comme

if (condition)
    do something; do something else;

sont difficiles à trouver.

Tobias
la source
Je suis curieux de savoir dans quel scénario le manque d'accolades a rendu la condition if vraie, pouvez-vous vous en souvenir ou en donner un exemple concret?
gitsitgo
L'expression conditionnelle est toujours évaluée avant l'instruction. Je suis également très curieux de voir un exemple réel de cela car cela représenterait un bug dans l'interpréteur.
Point
-1

Je voudrais juste noter que vous pouvez également laisser les accolades hors de l'autre. Comme vu dans cet article de John Resig's .

if(2 == 1){
    if(1 == 2){
        console.log("We will never get here")
    }
} else 
    console.log("We will get here")
Johnston
la source
Le [style d'accolades Qt] [1] nécessite des blocs des deux côtés d'un elsepour correspondre à l'utilisation d'accolades - cet exemple nécessiterait les accolades sur le elsebloc afin de passer une révision de code. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgrease
Pourquoi le vote négatif? La déclaration ci-dessus est exacte à 100%.
Johnston
-1

Il existe un moyen d'obtenir plusieurs lignes non accolades si des instructions. (Wow what anglais ..) mais c'est un peu tedius:

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


function funcName(){
  //Do Stuff Here...
}
amanuel2
la source
Vous n'avez pas besoin d'avoir autant de nouvelles lignes lorsque vous omettez les accolades. Ce qui précède peut également être écrit sur deux lignes comme: if (true) funcName()et else return null
phobos