Chaves são necessárias em declarações de uma linha em JavaScript?

161

Certa vez, ouvi dizer que deixar o aparelho em declarações de uma linha poderia ser prejudicial no JavaScript. Não me lembro mais do raciocínio e uma pesquisa no Google não ajudou muito.

Existe alguma coisa que faz com que seja uma boa ideia colocar todas as instruções entre chaves no JavaScript?

Estou perguntando, porque todo mundo parece fazê-lo.

Torre
fonte
5
Nota: somente a primeira declaração está assumindo o escopo, mesmo que você tenha várias declarações em uma linha, portanto, não são "declarações de uma linha", mas apenas uma declaração
Kris Ivanov
1
Você pode estar pensando no problema descrito nesta resposta
Blorgbeard saiu
@ Blorgbeard: não, eu realmente respondi a essa resposta há um tempo atrás.
Torre
Hah, entendo. Não importa, então :)
Blorgbeard saiu
Aqui está sua resposta: medium.com/@jonathanabrams/…
Erwan Legrand

Respostas:

203

Não

Mas eles são recomendados. Se você expandir a declaração, precisará delas.

Isso é perfeitamente válido

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

No entanto, é altamente recomendável que você sempre use chaves, porque se você (ou outra pessoa) expandir a declaração, isso será necessário.

Essa mesma prática segue em todas as linguagens de estilo de sintaxe C com chave. C, C ++, Java e até PHP suportam instruções de uma linha sem chaves. Você precisa perceber que está salvando apenas dois caracteres e, com os estilos estimulantes de algumas pessoas, nem sequer está salvando uma linha. Eu prefiro um estilo completo (como segue), por isso tende a ser um pouco mais longo. A troca é atendida muito bem com o fato de você ter uma legibilidade de código extremamente clara.

if (cond) 
{
    alert("Condition met!")
}
else
{
    alert("Condition not met!")
}
Josh K
fonte
28
+1, resposta informativa. Pessoalmente, nunca achei útil fazer essa coisa "recomendada". Eu nunca codifiquei python, então não apenas insiro as coisas e espero que o recuo seja importante. Se eu adicionar uma instrução, também adicionarei chaves. Sempre. Não me lembro de uma única vez que me mordeu. Não em C, não em C # e não em JavaScript.
Jakob
16
@Kirk: Douglas Crockford recomenda. Concordo que é uma decisão pessoal subjetiva, mas ao trabalhar em grupo, é mais fácil digitar o aparelho.
Josh K
10
@ Josh, oh, bem Crockford disse isso. Essa deve ser a palavra final. ;) (brincadeirinha) A questão é que a subjetividade deste ponto se estende por todos os idiomas do tipo C, e opiniões fortes podem ser encontradas por toda parte (para ambas as posições).
precisa saber é o seguinte
11
Minha experiência pessoal mostra que não colocar braçadeiras pode levar a grandes estragos ao trabalhar em equipes.
Senhores
4
É uma boa prática usar sempre o aparelho {}. Como o @Arx disse, há muito mais espaço para erros se você os deixar de fora. A Apple ainda tinha um bug no iOS SSL / TLS porque não usar chaves
Keenan Lidral-Porter
94

Há um aspecto de legibilidade - quando você tem instruções compostas, pode ficar muito confuso. Recuar ajuda, mas não significa nada para o 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

E depois há um aspecto de extensibilidade:

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

O pensamento é que, se você sempre tiver colchetes, precisará inserir outras instruções dentro desse bloco.

Rudu
fonte
4
É por isso que devemos sempre usá-lo como one-liner: if (a===true) alert(a);. Agora está claro!
João Pimentel Ferreira
1
Usar o colchete encaracolado esquerdo e o colchete encaracolado direito torna os condicionais claros. Para os sonhadores entre nós, também conhecido como o pássaro voando esquerdo e direito.
HalfMen
61

A pergunta pergunta sobre declarações em uma linha. No entanto, os muitos exemplos fornecidos mostram razões para não deixar de fora as chaves com base em várias declarações de linha. É totalmente seguro não usar colchetes em uma linha, se esse for o estilo de codificação que você preferir.

Por exemplo, a pergunta pergunta se está tudo bem:

 if (condition) statement;

Não pergunta se está tudo bem:

 if (condition)
   statement;

Eu acho que deixar colchetes de fora é preferível, porque torna o código mais legível com sintaxe menos supérflua.

Meu estilo de codificação é nunca usar colchetes, a menos que o código seja um bloco. E nunca usar várias instruções em uma única linha (separadas por ponto e vírgula). Acho isso fácil de ler e claro e nunca tenho problemas de escopo nas declarações 'if'. Como resultado, o uso de colchetes em uma única declaração if condition exigiria 3 linhas. Como isso:

 if (condition) {
   statement;
 }

Usar uma linha if é preferível, pois usa menos espaço vertical e o código é mais compacto.

Eu não forçaria outras pessoas a usar esse método, mas funciona para mim e não poderia discordar mais dos exemplos fornecidos sobre como deixar de fora os colchetes leva a erros de codificação / escopo.

Peawormsworth
fonte
1
Sempre achei que alguém deveria sempre incluir aparelho ... mas estou repensando agora. Você tem o guia de estilo do airbnb ao seu lado!
Senderle
1
No entanto, você esquece que a maioria dos formatadores de código altera isso para um formato de 2 linhas e você volta ao código problemático. O argumento do espaço vertical é simplesmente bobo. A legibilidade sempre vence e as telas de hoje são enormes.
Kim
1
As 2 linhas adicionadas para cada colchete, para cercar as instruções de uma linha, não são um grande custo em comparação com um dano potencial que pode ser causado por um - mesmo desenvolvedor muito cuidadoso - mantendo seu código. Você mesmo pode ser um grande desenvolvedor com habilidades míticas, mas não pode assumir que seus colegas são. BEIJO, envolva as coisas com um contexto e torne o mais fácil possível para os outros, ou você acabará tendo problemas.
Maciej Tokarz
@senderle A regra eslint para controlar esta pode ser encontrada aqui: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
silkfire
15

Tecnicamente não, mas de outra forma absolutamente Sim !!!

Esqueça "É uma preferência pessoal", "o código funcionará bem", "está funcionando bem para mim", "é mais legível" yada yada BS. Isso pode facilmente levar a problemas muito sérios se você cometer um erro e, acredite, é muito fácil cometer um erro durante a codificação (não acredite?), Confira a famosa Apple falha ).

Argumento: "É preferência pessoal"

Não não é. A menos que você seja uma equipe de um homem saindo em Marte, não. Na maioria das vezes, haverá outras pessoas lendo / modificando seu código. Em qualquer equipe séria de codificação, essa será a maneira recomendada, portanto não é uma 'preferência pessoal'.

Argumento: "o código funcionará perfeitamente"

O mesmo acontece com o código do espaguete! Isso significa que está tudo bem em criá-lo?

Argumento: "tem funcionado bem para mim"

Na minha carreira, vi muitos bugs criados por causa desse problema. Você provavelmente não se lembra de quantas vezes comentou 'DoSomething()'e ficou perplexo com o motivo 'SomethingElse()':

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

Ou acrescentou 'SomethingMore' e não percebeu que não será chamado (mesmo que o recuo implique o contrário):

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

Aqui está um exemplo da vida real que eu tive. Alguém queria desativar todos os logs para executar find & replace "console.log"=> //"console.log":

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

Vê o problema?

Mesmo se você pensar, "estes são tão triviais, eu nunca faria isso"; lembre-se de que sempre haverá um membro da equipe com habilidades de programação inferiores a você (espero que você não seja o pior da equipe!)

Argumento: "é mais legível"

Se eu aprendi alguma coisa sobre programação, é que as coisas simples se tornam muito complexas muito rapidamente. É muito comum que isso:

if (condition) 
    DoSomething();

se transforma no seguinte após ter sido testado com diferentes navegadores / ambientes / casos de uso ou novos recursos adicionados:

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

E compare com isso:

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

PS: Os pontos de bônus são para quem notou o erro no exemplo acima.

Caner
fonte
2
bem, o erro óbvio é o DoSomethingMore (); Mas há também outro bug. se a for nulo eb for nulo, você receberá apenas o "erro b", nunca receberá o "erro a".
rocketsarefast
Pelos seus exemplos, sua equipe de desenvolvimento não sabe como codificar, o aparelho não os ajudará ...
Carlos ABS
alguns dos exemplos são da equipe de desenvolvedores da Apple
Caner
13

Não há problema de manutenção!

O problema com todos vocês é que você coloca ponto e vírgula em todos os lugares. Você não precisa de chaves para várias instruções. Se você deseja adicionar uma instrução, use vírgulas.

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

Este é um código válido que será executado como você espera!

william malo
fonte
2
Você não quer dizer if, elsee alerte não If, Elsee Alert?
Anish Gupta
Uau, eu não sabia disso, obrigado por me informar! Parece que a maioria das pessoas deixa de fora esse detalhe importante.
Hendeca
13
Enquanto isso funciona em JavaScript, está além de mim o motivo de você querer fazer isso. Estou arriscando um palpite de que a maioria dos desenvolvedores não está ciente disso (inclusive eu antes de ler isso), que eu suspeito que logo se tornaria um problema de manutenção entre os desenvolvedores. Às vezes, a maneira mais inteligente não é a melhor.
7114 Simon
14
Isto é horrível. Se alguém adicionar uma declaração e se esquecer de transformar o ponto-e-vírgula em uma vírgula na última penúltima instrução do bloco, você terá um bug que pode ser muito difícil de identificar, porque a vírgula e o ponto-e-vírgula no final da linha também parecem muito semelhante.
Ingo Bürk
1
Prefiro uma abordagem "hemingwayiana" : muito limpa. E sem espaço entre ife (, comoif(true) doSomething();
victorf
8

Não há motivo de programação para usar os chavetas em instruções de uma linha.

Isso se resume apenas às preferências e legibilidade dos codificadores.

Seu código não será quebrado por causa disso.

Yahel
fonte
7

Além do motivo mencionado por Josh K (que também se aplica a Java, C etc.), um problema especial no JavaScript é a inserção automática de ponto e vírgula . Do exemplo da Wikipedia:

return
a + b;

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

Portanto, isso também pode gerar resultados inesperados, se usado assim:

if (x)
   return
   a + b;

Não é realmente muito melhor escrever

if (x) {
   return
   a + b;
}

mas talvez aqui o erro seja um pouco mais fácil de detectar (?)

Chris Lercher
fonte
Todos esses exemplos me parecem horríveis, a menos que os escritores sejam temporários e pagos por linha ou até que funcione.
Cees Timmerman
6

É uma questão de estilo, mas o aparelho é bom para evitar possíveis balanços .

pausa
fonte
4

Existem muitas respostas boas, então não vou repetir, exceto quando digo minha “regra” quando os aparelhos podem ser omitidos: em condições que 'retornam' ou 'jogam' (por exemplo) como sua única declaração . Nesse caso, o controle de fluxo já está claro que está finalizando:

Até o "caso ruim" pode ser rapidamente identificado (e corrigido) devido ao controle de fluxo final. Este conceito / estrutura de “regra” também se aplica a vários idiomas.

if (x)
    return y;
    always();

Claro, também é por isso que se pode usar um linter.

user2864740
fonte
3

Aqui está o porquê é recomendado

Digamos que eu escreva

if(someVal)
    alert("True");

Em seguida, o próximo desenvolvedor chega e diz "Ah, eu preciso fazer outra coisa", então eles escrevem

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

Agora, como você pode ver, "AlsoTrue" sempre será verdadeiro, porque o primeiro desenvolvedor não usou chaves.

Amir Raminfar
fonte
Isso não está correto, você está perdendo o 'else': if (someVal) alert ("True"); else alert ("AlsoTrue"); estaria correto. Eu não o usaria porque gosto do {}, pois é muito melhor legível.
Gerrit B
1
Hã? Eu não tinha outra declaração. Eu estava dizendo que sem aparelho, isso pode levar a erros se alguém adicionar uma nova linha. Eu acho que você não entendeu meu argumento.
Amir Raminfar
Acho que o que ele está dizendo é que, a segunda linha será executada, não importa o quê. Uma instrução If sem chaves pode executar apenas 1 linha.
PostCodeism
3

Atualmente, estou trabalhando em um minifier. Mesmo agora eu verifico em dois scripts enormes. Experimentalmente, descobri: você pode remover os chavetas atrás de for, if, else, while, function * se os chavetas não incluírem ';', 'return', 'for', 'if', 'else', 'while', 'do', 'function'. Quebra de linha independente.

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

É claro que você precisa substituir a chave de fechamento por um ponto e vírgula, se não for seguida por outra chave de fechamento.

Uma função não deve terminar em vírgula.

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

Testado no Chrome e FF.

BF
fonte
2

Sempre achei que

if(valid) return;

é mais fácil para os meus olhos do que

if(valid) {
  return;
}

também condicional como

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

são mais fáceis de ler (minha opinião pessoal) do que

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

mas acho que tudo se resume ao estilo de codificação

Yogi
fonte
2

Não respondendo diretamente à pergunta, mas abaixo está uma sintaxe curta sobre se a condição em uma linha

Ex:

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

Pode ser escrito assim:

var i=true;
i && dosomething();
Alee
fonte
1

Existem muitos problemas no javascript. Dê uma olhada no arquiteto JavaScript Douglas Crockford falando sobre isso. A declaração if parece boa, mas a declaração return pode apresentar um problema.

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

return{
    ok:true;
}
//works well in javascript
kamayd
fonte
1

Encontrei esta resposta pesquisando sobre uma experiência semelhante e decidi respondê-la com a minha experiência.

As instruções sem suporte funcionam na maioria dos navegadores, no entanto, eu testei que os métodos sem suporte na verdade não funcionam em alguns navegadores.

Em 26 de fevereiro de 2018, esta declaração funcionaria em Pale Moon, mas não no Google Chrome.

function foo()
   return bar;
Gabriel I.
fonte
0

O nível de indentação inicial de uma instrução deve ser igual ao número de chaves abertas acima dela. (excluindo chaves entre aspas ou comentadas ou nas diretivas de pré-processador)

Caso contrário, K&R seria um bom estilo de indentação. Para fixar o estilo deles, recomendo colocar instruções if simples e curtas em uma linha.

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

ao invés de

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

Se eu estivesse escrevendo um editor, faria com que o botão de formato automático sugasse a barra até a mesma linha que foo e o faria inserir chaves ao redor da barra se você pressionar return antes:

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

É fácil e consistente adicionar novas instruções acima ou abaixo da barra no corpo da instrução if

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

Às vezes eles parecem ser necessários! Eu não podia acreditar, mas ontem me ocorreu em uma sessão do Firebug (recente Firefox 22.0) que

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

executado faça algo apesar de my.condition.key ser verdadeiro . Adicionando chaves:

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

corrigiu esse assunto. Existem inúmeros exemplos em que aparentemente funciona sem aparelhos, mas nesse caso definitivamente não funcionou.

As pessoas que tendem a colocar mais de uma declaração em uma linha definitivamente devem sempre usar aparelho, é claro, porque coisas como

if (condition)
    do something; do something else;

são difíceis de encontrar.

Tobias
fonte
Estou curioso em saber em que cenário a falta de aparelhos tornou a condição if verdadeira, você pode se lembrar ou dar um exemplo real disso?
gitsitgo
A expressão condicional é sempre avaliada antes da instrução. Também estou muito curioso para ver um exemplo real disso, porque isso representaria um erro no intérprete.
Ponto-
-1

Gostaria apenas de observar que você também pode deixar o aparelho fora do resto. Como visto neste artigo por John Resig's .

if(2 == 1){
    if(1 == 2){
        console.log("We will never get here")
    }
} else 
    console.log("We will get here")
Johnston
fonte
O [estilo de chaves Qt] [1] requer blocos nos dois lados de um elsepara corresponder ao uso de chaves - este exemplo exigiria as chaves no elsebloco para passar por uma revisão de código. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgrease
Por que o voto negativo? A afirmação acima é 100% precisa.
Johnston
-1

Existe uma maneira de obter várias linhas de chaves não encaracoladas if (Uau, que inglês ..), mas é meio tedius:

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


function funcName(){
  //Do Stuff Here...
}
amanuel2
fonte
Você não precisa ter tantas linhas novas ao omitir chaves. O texto acima também pode ser escrito em duas linhas como: if (true) funcName()e else return null
phobos