¿Son necesarias las llaves en las declaraciones de una línea en JavaScript?


162

Una vez escuché que dejar las llaves en las declaraciones de una línea podría ser dañino en JavaScript. Ya no recuerdo el razonamiento y una búsqueda en Google no ayudó mucho.

¿Hay algo que haga que sea una buena idea rodear todas las declaraciones entre llaves en JavaScript?

Estoy preguntando, porque todos parecen hacerlo.


55
Nota: solo la primera declaración asume el alcance, incluso si tiene varias declaraciones en una línea, por lo que no se trata de "declaraciones de una línea", sino más bien una declaración única
Kris Ivanov

1
Quizás esté pensando en el problema descrito en esta respuesta
Blorgbeard sale el

@Blorgbeard: no, en realidad respondí a esa respuesta hace un tiempo.
Torre el

Ja, eso veo. No importa entonces :)
Blorgbeard sale el

Aquí está su respuesta: medium.com/@jonathanabrams/…
Erwan Legrand

Respuestas:


203

No

Pero son recomendables. Si alguna vez expande la declaración, los necesitará.

Esto es perfectamente valido

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

Sin embargo, es muy recomendable que siempre use llaves, ya que si usted (u otra persona) expande la declaración, será necesario.

Esta misma práctica sigue en todos los lenguajes de estilo de sintaxis C con arriostramiento. C, C ++, Java e incluso PHP admiten una declaración de línea sin llaves. Debes darte cuenta de que solo estás guardando dos caracteres y con los estilos de refuerzo de algunas personas ni siquiera estás guardando una línea. Prefiero un estilo de llave completa (como el siguiente), por lo que tiende a ser un poco más largo. La compensación se cumple muy bien con el hecho de que tiene una legibilidad de código extremadamente clara.

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

28
+1, respuesta informativa. Sin embargo, personalmente, nunca me pareció útil hacer esta cosa "recomendada". Nunca he codificado Python, así que no solo inserto cosas y espero que la sangría importe. Si agrego una declaración, también agrego llaves. Siempre. No recuerdo una sola vez que me mordió. No en C, no en C #, no en JavaScript.
Jakob

16
@ Kirk: Douglas Crockford lo recomienda. Estoy de acuerdo en que es una decisión personal subjetiva, pero cuando se trabaja en un grupo, es más fácil simplemente escribir las llaves.
Josh K

10
@ Josh, oh, bueno, Crockford lo dijo. Esa debe ser la última palabra. ;) (es broma) El problema es que la subjetividad de este punto se extiende a todos los lenguajes tipo C, y se pueden encontrar opiniones fuertes en todas partes (para ambas posiciones).
Kirk Woll

11
Mi experiencia personal muestra que no colocar brazaletes puede conducir a grandes errores cuando se trabaja en equipos.
Señores

44
Es una buena práctica usar siempre las llaves {}. Como dijo @Arx, hay mucho más margen de error si los deja fuera. Apple incluso tuvo un error en el SSL / TLS de iOS porque no usaban aparatos ortopédicos
Keenan Lidral-Porter el

94

Hay un aspecto de legibilidad: cuando tienes declaraciones compuestas puede ser muy confuso. La sangría ayuda pero no significa nada para el compilador / intérprete.

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

Y luego hay un aspecto de extensibilidad:

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

Se piensa que si siempre tiene los corchetes, entonces sabe insertar otras declaraciones dentro de ese bloque.


44
Es por eso que siempre se debe utilizar como una sola línea: if (a===true) alert(a);. ¡Ahora está claro!
João Pimentel Ferreira

1
El uso del soporte rizado izquierdo y el soporte derecho rizado deja en claro los condicionales. Para los soñadores entre nosotros, también conocido como el ave voladora izquierda y derecha.
HalfMens

61

La pregunta se refiere a declaraciones en una línea. Sin embargo, los muchos ejemplos proporcionados muestran razones para no omitir llaves basadas en declaraciones de varias líneas. Es completamente seguro no usar corchetes en una línea, si ese es el estilo de codificación que prefiere.

Por ejemplo, la pregunta pregunta si esto está bien:

 if (condition) statement;

No pregunta si esto está bien:

 if (condition)
   statement;

Creo que es preferible dejar los corchetes porque hace que el código sea más legible con una sintaxis menos superflua.

Mi estilo de codificación es nunca usar corchetes a menos que el código sea un bloque. Y nunca usar múltiples declaraciones en una sola línea (separadas por punto y coma). Encuentro esto fácil de leer y claro y nunca tengo problemas de alcance en las declaraciones 'if'. Como resultado, el uso de corchetes en una sola declaración de condición requeriría 3 líneas. Me gusta esto:

 if (condition) {
   statement;
 }

Usar una línea si la declaración es preferible porque usa menos espacio vertical y el código es más compacto.

No forzaría a otros a usar este método, pero funciona para mí y no podría estar más en desacuerdo con los ejemplos proporcionados sobre cómo dejar los corchetes conduce a errores de codificación / alcance.


1
Siempre sentí que uno siempre debería incluir llaves ... pero lo estoy repensando ahora. ¡Tienes la guía de estilo de airbnb a tu lado!
senderle

1
Sin embargo, olvida que la mayoría de los formateadores de código lo cambian a un formato de 2 líneas y vuelve al código problemático. El argumento del espacio vertical es simplemente tonto. La legibilidad siempre gana, y las pantallas de hoy son enormes.
Kim

1
Las 2 líneas agregadas para cada paréntesis, para rodear sus declaraciones de una línea, no son un gran costo en comparación con un daño potencial que puede ser causado por un desarrollador, incluso muy cuidadoso, que mantiene su código. Usted mismo puede ser un gran desarrollador con habilidades míticas, pero no puede asumir que sus colegas lo son. BESO, envuelve las cosas con un contexto y hazlo lo más fácil posible para los demás o eventualmente te meterás en problemas.
Maciej Tokarz

@senderle La regla de eslint para controlar esto se puede encontrar aquí: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
silkfire

15

Técnicamente no, pero por lo demás absolutamente ¡Sí!

Olvídate de "Es preferencia personal", "el código funcionará bien", "me ha funcionado bien", "es más legible" yada yada BS. Esto podría conducir fácilmente a problemas muy serios si comete un error y créame, es muy fácil cometer un error cuando está codificando (¿No cree ?, vea el famoso error de falla de Apple ).

Argumento: "Es preferencia personal"

No, no es. A menos que sea un equipo de un solo hombre que se vaya a Marte, no. La mayoría de las veces habrá otras personas leyendo / modificando su código. En cualquier equipo de codificación serio, esta será la forma recomendada, por lo que no es una 'preferencia personal'.

Argumento: "el código se ejecutará bien"

¡También el código de espagueti! ¿Significa que está bien crearlo?

Argumento: "ha funcionado bien para mí"

En mi carrera he visto tantos errores creados debido a este problema. Probablemente no recuerdes cuántas veces has comentado 'DoSomething()'y desconcertado por qué 'SomethingElse()'se llama:

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

O agregó 'SomethingMore' y no notó que no se llamará (aunque la sangría implica lo contrario):

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

Aquí hay un ejemplo de la vida real que tuve. Alguien quería desactivar todos los registros para ejecutar find & replace "console.log"=> //"console.log":

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

¿Ves el problema?

Incluso si piensas, "estos son tan triviales, nunca haría eso"; recuerda que siempre habrá un miembro del equipo con habilidades de programación inferiores a las tuyas (¡ojalá no seas el peor del equipo!)

Argumento: "es más legible"

Si he aprendido algo sobre programación, es que las cosas simples se vuelven muy complejas muy rápidamente. Es muy común que esto:

if (condition) 
    DoSomething();

se convierte en lo siguiente después de que se haya probado con diferentes navegadores / entornos / casos de uso o se hayan agregado nuevas funciones:

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

Y compáralo con esto:

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

PD: Los puntos de bonificación van a quienes notaron el error en el ejemplo anterior.


2
bueno, el error obvio es DoSomethingMore (); Pero también hay otro error. si a es nulo yb es nulo, solo obtendrá "error b", nunca obtendrá "error a".
rocketsarefast

Según sus ejemplos, su equipo de desarrollo no sabe cómo codificar en absoluto, las llaves no los ayudarán ...
Carlos ABS

algunos de los ejemplos son del equipo de desarrolladores de Apple
Caner

13

¡No hay problema de mantenimiento!

El problema con todos ustedes es que ponen punto y coma en todas partes. No necesita llaves para múltiples declaraciones. Si desea agregar una declaración, solo use comas.

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

¡Este es un código válido que se ejecutará como esperabas!


2
¿No quieres decir if, elsey alerty no If, Elsey Alert?
Anish Gupta

Wow, no sabía esto, ¡gracias por informarme! Parece que la mayoría de la gente deja de lado este detalle importante.
Hendeca

13
Si bien esto funciona en JavaScript, no sé por qué querrías hacerlo. Me atrevo a suponer que la mayoría de los desarrolladores no son conscientes de esto (incluido yo mismo antes de leer esto), lo que sospecho que se convertiría rápidamente en un problema de mantenimiento entre los desarrolladores. A veces, la forma más inteligente no es la mejor.
Simon

14
Esto es horrible Si alguien agrega una declaración y se olvida de convertir el punto y coma en una coma en la penúltima declaración del bloque, tiene un error que puede ser realmente difícil de detectar porque la coma y el punto y coma al final de la línea también se ven similar.
Ingo Bürk

1
Prefiero un enfoque "hemingwayiano" : muy limpio. Y sin espacio entre ify (, comoif(true) doSomething();
victorf

8

No hay ninguna razón de programación para usar las llaves en declaraciones de una línea.

Esto solo se reduce a las preferencias y legibilidad de los codificadores.

Tu código no se romperá por eso.


7

Además del motivo mencionado por @Josh K (que también se aplica a Java, C, etc.), un problema especial en JavaScript es la inserción automática de punto y coma . Del ejemplo de Wikipedia:

return
a + b;

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

Entonces, esto también puede producir resultados inesperados, si se usa así:

if (x)
   return
   a + b;

No es mucho mejor escribir

if (x) {
   return
   a + b;
}

pero tal vez aquí el error es un poco más fácil de detectar (?)


Todos esos ejemplos me parecen horribles, a menos que los escritores sean temporales y se paguen por línea o hasta que funcione.
Cees Timmerman


4

Hay muchas buenas respuestas, por lo que no repetiré, excepto para decir mi "regla" cuando se pueden omitir los aparatos ortopédicos: en condiciones que "devuelven" o "arrojan" (por ejemplo) como su única declaración . En este caso, el control de flujo ya está claro que está terminando:

Incluso el "mal caso" puede identificarse rápidamente (y repararse) debido al control de flujo de terminación. Esta "regla" de concepto / estructura también se aplica a varios idiomas.

if (x)
    return y;
    always();

Por supuesto, esta es también la razón por la que uno podría usar un linter ...


3

Aquí es por qué se recomienda

Digamos que escribo

if(someVal)
    alert("True");

Luego viene el próximo desarrollador y dice "Oh, necesito hacer otra cosa", y escriben

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

Ahora, como puede ver, "AlsoTrue" siempre será cierto, porque el primer desarrollador no usó llaves.


Eso no es correcto, te estás perdiendo la alerta 'else': if (someVal) ("True"); otra alerta ("AlsoTrue"); Sería correcto. No lo usaría porque me gusta el {} porque es mucho mejor legible.
Gerrit B

1
¿Eh? No tenía una declaración más. Estaba diciendo que sin llaves, puede provocar errores si alguien agrega una nueva línea. Creo que no entendiste mi punto.
Amir Raminfar

Creo que lo que está diciendo es que la segunda línea se ejecutará sin importar qué. Una instrucción If sin llaves solo puede ejecutar 1 línea.
PostCodeism

3

Actualmente estoy trabajando en un minificador. Incluso ahora lo reviso en dos scripts enormes. Experimentalmente lo descubrí: puede quitar las llaves detrás de, si, de lo contrario, mientras, funciona * si las llaves no incluyen ';', 'return', 'for', 'if', 'else', 'while', 'do', 'function'. Saltos de línea independientes.

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

Por supuesto, debe reemplazar la llave de cierre con un punto y coma si no le sigue otra llave de cierre.

Una función no debe terminar en una coma.

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

Probado en Chrome y FF.


2

Siempre encontré que

if(valid) return;

es más fácil para mi ojo que

if(valid) {
  return;
}

también condicional como

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

son más fáciles de leer (mi opinión personal) en lugar de

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

pero supongo que todo se reduce al estilo de codificación


2

No responde la pregunta directamente, pero a continuación hay una breve sintaxis sobre la condición if en una línea

Ex:

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

Se puede escribir así:

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


1

Encontré esta respuesta buscando una experiencia similar, así que decidí responderla con mi experiencia.

Las declaraciones sin corchetes funcionan en la mayoría de los navegadores, sin embargo, probé que los métodos sin corchetes de hecho no funcionan en algunos navegadores.

A partir del 26 de febrero de 2018, esta declaración funciona en Pale Moon, pero no en Google Chrome.

function foo()
   return bar;

0

El nivel inicial de sangría de una declaración debe ser igual al número de llaves abiertas por encima de ella. (excluyendo llaves o comillas citadas o comentadas en las directivas de preprocesador)

De lo contrario, K&R sería un buen estilo de sangría. Para arreglar su estilo, recomiendo colocar declaraciones if cortas y simples en una línea.

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

en vez de

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

Si estuviera escribiendo un editor, haría que su botón de formato automático succione la barra hasta la misma línea que foo, y lo haría insertar llaves alrededor de la barra si presiona Intro antes de esto:

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

Entonces es fácil y consistente agregar nuevas declaraciones encima o debajo de la barra dentro del cuerpo de la declaración if

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

-1

¡A veces parecen ser necesarios! No podía creerlo, pero ayer se me ocurrió en una sesión de Firebug (reciente Firefox 22.0) que

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

ejecutado hacer algo a pesar de que my.condition.key era cierto . Agregar llaves:

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

Arreglado ese asunto. Hay miles de ejemplos en los que aparentemente funciona sin las llaves, pero en este caso definitivamente no lo hizo.

Las personas que tienden a poner más de una declaración en una línea siempre deben usar llaves, por supuesto, porque cosas como

if (condition)
    do something; do something else;

Son difíciles de encontrar.


Tengo curiosidad sobre en qué escenario la falta de frenos hizo que la condición sea verdadera, ¿puede recordar o dar un ejemplo real de ello?
gitsitgo

La expresión condicional siempre se evalúa antes de la declaración. También tengo mucha curiosidad por ver un ejemplo real de esto porque representaría un error en el intérprete.
Semicolon

-1

Solo me gustaría señalar que también puede dejar las llaves fuera de lo demás. Como se ve en este artículo de John Resig's .

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

El [Estilo de llaves Qt] [1] requiere bloques en ambos lados de una elsepara que coincida con el uso de llaves; este ejemplo requeriría llaves en el elsebloque para pasar una revisión de código. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgrease

¿Por qué el voto negativo? La declaración anterior es 100% precisa.
Johnston

-1

Hay una manera de lograr llaves de línea múltiple no rizadas si declaraciones ... (Wow qué inglés ...) pero es un poco tedio:

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


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

No es necesario tener tantas líneas nuevas al omitir llaves. Lo anterior también se puede escribir en dos líneas como: if (true) funcName()y else return null
phobos
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.