Czy nawiasy klamrowe są potrzebne w jednowierszowych instrukcjach JavaScript?


163

Słyszałem kiedyś, że pozostawienie nawiasów klamrowych w jednowierszowych wypowiedziach może być szkodliwe w JavaScript. Nie pamiętam już powodu, a wyszukiwanie w Google niewiele pomogło.

Czy jest coś, co sprawia, że ​​dobrym pomysłem jest umieszczenie wszystkich instrukcji w nawiasach klamrowych w JavaScript?

Pytam, bo wydaje się, że wszyscy to robią.


5
Uwaga: tylko pierwsza instrukcja zakłada zakres, nawet jeśli masz kilka instrukcji w jednej linii, więc nie jest to „jedna instrukcja”, ale raczej pojedyncza instrukcja
Kris Ivanov

1
Być może myślisz o problemie opisanym w tej odpowiedzi
Blorgbeard wyszedł

@Blorgbeard: nie, tak naprawdę odpowiedziałem na tę odpowiedź jakiś czas temu.
Tower

Hah, więc rozumiem. Nieważne :)
Blorgbeard wychodzi

Odpowiedzi:


204

Nie

Ale są zalecane. Jeśli kiedykolwiek rozszerzysz stwierdzenie, będziesz ich potrzebować.

To jest całkowicie słuszne

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

Jednak zdecydowanie zaleca się, aby zawsze używać nawiasów klamrowych, ponieważ jeśli Ty (lub ktoś inny) kiedykolwiek rozwiniesz instrukcję, będzie to wymagane.

Ta sama praktyka jest stosowana we wszystkich językach w stylu składni C z nawiasami klamrowymi. C, C ++, Java, a nawet PHP obsługują jedną instrukcję bez nawiasów klamrowych. Musisz zdać sobie sprawę, że ratujesz tylko dwie postacie, a przy niektórych stylach usztywniających nie oszczędzasz nawet linii. Wolę pełny styl nawiasów klamrowych (jak poniżej), więc wydaje się być nieco dłuższy. Kompromis jest bardzo dobrze spełniany dzięki temu, że masz wyjątkowo czytelny kod.

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

28
+1, pouczająca odpowiedź. Osobiście jednak nigdy nie uważałem za przydatne robienie tej „zalecanej” rzeczy. Nigdy nie kodowałem Pythona, więc nie tylko wstawiam rzeczy i oczekuję, że wcięcie będzie miało znaczenie. Jeśli dodam oświadczenie, dodaję również nawiasy klamrowe. Zawsze. Nie pamiętam ani razu, kiedy mnie to ugryzło. Nie w C, nie w C # ani w JavaScript.
Jakob

16
@Kirk: Douglas Crockford poleca to. Zgadzam się, że to subiektywna, osobista decyzja, ale pracując w grupie łatwiej jest po prostu wpisać aparat.
Josh K,

10
@Josh, och, cóż, Crockford to powiedział. To musi być ostatnie słowo. ;) (tylko żartuję) Problem w tym, że subiektywność tego punktu rozciąga się na wszystkie języki podobne do C i można znaleźć silne opinie w całym tekście (dla obu stanowisk).
Kirk Woll

11
Moje osobiste doświadczenie pokazuje, że nie zakładanie karwaszów może prowadzić do poważnych wpadek podczas pracy w zespołach.
Panowie,

4
Dobrą praktyką jest zawsze używanie nawiasów klamrowych {}. Jak powiedział @Arx, jest dużo więcej miejsca na błędy, jeśli je pominiesz. Apple miał nawet błąd w SSL / TLS iOS, ponieważ nie używali nawiasów klamrowych
Keenan Lidral-Porter

94

Jest aspekt czytelności - gdy masz złożone instrukcje, może to być bardzo zagmatwane. Wcięcie pomaga, ale nic nie znaczy dla kompilatora / interpretera.

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

Jest też aspekt rozszerzalności:

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

Uważa się, że jeśli zawsze masz nawiasy, to wiesz, że możesz wstawić inne instrukcje wewnątrz tego bloku.


4
Dlatego zawsze powinniśmy używać go jako jedną wkładką: if (a===true) alert(a);. Teraz jest jasne!
João Pimentel Ferreira

1
Użycie lewego-nawiasu klamrowego i prawego-nawiasu klamrowego powoduje, że warunki warunkowe są jasne. Dla śniących wśród nas, nazywany również lewym i prawym latającym ptakiem.
HalfMens

61

Pytanie dotyczy wypowiedzi w jednej linii. Jednak wiele podanych przykładów pokazuje powody, dla których nie należy pomijać nawiasów klamrowych opartych na wielu wierszach instrukcji. Całkowicie bezpieczne jest nie używanie nawiasów w jednej linii, jeśli preferujesz taki styl kodowania.

Na przykład pytanie brzmi, czy to jest w porządku:

 if (condition) statement;

Nie pyta, czy to jest w porządku:

 if (condition)
   statement;

Myślę, że pozostawienie nawiasów jest lepsze, ponieważ sprawia, że ​​kod jest bardziej czytelny przy mniej zbędnej składni.

Mój styl kodowania to nigdy nie używać nawiasów, chyba że kod jest blokiem. I nigdy nie używać wielu instrukcji w jednym wierszu (oddzielonych średnikami). Uważam, że jest to łatwe do odczytania i zrozumiałe, i nigdy nie mam problemów ze określaniem zakresu w stwierdzeniach „jeśli”. W rezultacie użycie nawiasów w pojedynczej instrukcji warunku if wymagałoby 3 wierszy. Lubię to:

 if (condition) {
   statement;
 }

Preferowane jest użycie jednego wiersza instrukcji if, ponieważ zajmuje mniej miejsca w pionie, a kod jest bardziej zwarty.

Nie zmuszałbym innych do korzystania z tej metody, ale działa ona dla mnie i nie mogę bardziej nie zgodzić się z podanymi przykładami, w których pominięcie nawiasów prowadzi do błędów w kodowaniu / określaniu zakresu.


1
Zawsze uważałem, że zawsze należy założyć aparat ortodontyczny ... ale teraz przemyślam to na nowo. Masz po swojej stronie przewodnik po stylu Airbnb !
senderle

1
Jednak zapominasz, że większość programów formatujących kod zmienia go na format dwuwierszowy i wracasz do problematycznego kodu. Argument spacji pionowej jest po prostu głupi. Czytelność zawsze wygrywa, a dzisiejsze ekrany są ogromne.
Kim

1
2 wiersze dodane dla każdego nawiasu, aby otoczyć jednowierszowe oświadczenia, nie stanowią dużego kosztu w porównaniu z potencjalnymi szkodami, które może spowodować - nawet bardzo ostrożny programista - konserwacja kodu. Ty sam możesz być świetnym programistą z mitycznymi umiejętnościami, ale nie możesz zakładać, że Twoi koledzy są. KISS, opakuj rzeczy w kontekst i spraw, by było to jak najłatwiejsze dla innych, inaczej w końcu wpadniesz w kłopoty.
Maciej Tokarz

@senderle Regułę eslint do kontrolowania tego można znaleźć tutaj: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
silkfire

15

Technicznie nie, ale poza tym absolutnie tak !!!

Zapomnij o „osobistych preferencjach”, „kod będzie działał dobrze”, „u mnie działa dobrze”, „jest bardziej czytelny” yada yada BS. Może to łatwo doprowadzić do bardzo poważnych problemów, jeśli popełnisz błąd i uwierz mi, bardzo łatwo jest popełnić błąd podczas kodowania (nie wierz ?, sprawdź słynny błąd Apple go to fail ).

Argument: „To osobiste preferencje”

Nie, nie jest. Chyba że jesteś jednoosobową drużyną wyjeżdżającą na Marsa, nie. W większości przypadków inne osoby będą czytały / modyfikowały Twój kod. W każdym poważnym zespole programistycznym będzie to zalecany sposób, więc nie jest to „osobiste preferencje”.

Argument: „kod będzie działał dobrze”

Tak samo jak kod spaghetti! Czy to znaczy, że można to stworzyć?

Argument: „u mnie działa dobrze”

W swojej karierze widziałem wiele błędów powstałych z powodu tego problemu. Prawdopodobnie nie pamiętasz, ile razy komentowałeś 'DoSomething()'i zastanawiałeś się, dlaczego 'SomethingElse()'nazywa się:

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

Lub dodał „SomethingMore” i nie zauważył, że nie zostanie wywołany (mimo że wcięcie sugeruje inaczej):

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

Oto przykład z życia wzięty. Ktoś chciał wyłączyć wszystkie rejestrowanie, więc uruchomił find & replace "console.log"=> //"console.log":

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

Widzisz problem?

Nawet jeśli myślisz: „to jest tak trywialne, nigdy bym tego nie zrobił”; pamiętaj, że zawsze znajdzie się członek zespołu o gorszych umiejętnościach programistycznych od Ciebie (miejmy nadzieję, że nie jesteś najgorszy w zespole!)

Argument: „jest bardziej czytelny”

Jeśli nauczyłem się czegokolwiek o programowaniu, to to, że proste rzeczy bardzo szybko stają się bardzo złożone. Bardzo często jest to:

if (condition) 
    DoSomething();

zmienia się w następujący po przetestowaniu go z różnymi przeglądarkami / środowiskami / przypadkami użycia lub dodaniu nowych funkcji:

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

I porównaj to z tym:

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

PS: Dodatkowe punkty trafiają do tego, kto zauważył błąd w powyższym przykładzie.


2
cóż, oczywistym błędem jest DoSomethingMore (); Ale jest też inny błąd. jeśli a jest zerowe i b jest zerowe, otrzymujesz tylko „błąd b”, nigdy nie otrzymasz „błędu a”.
rocketsarefast

Na podstawie twoich przykładów, twój zespół programistów w ogóle nie wie, jak kodować, klamry im nie pomogą ...
Carlos ABS

niektóre przykłady pochodzą od zespołu programistów Apple
Caner,

13

Nie ma problemu z konserwacją!

Problem z wami wszystkimi polega na tym, że wszędzie umieszczacie średniki. Nie potrzebujesz nawiasów klamrowych w przypadku wielu instrukcji. Jeśli chcesz dodać oświadczenie, użyj przecinków.

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

To jest prawidłowy kod, który będzie działał zgodnie z oczekiwaniami!


2
Nie masz na myśli if, elsea alertnie If, Elsei Alert?
Anish Gupta

Wow, nie wiedziałem tego, dziękuję za poinformowanie mnie! Wydaje się, że większość ludzi pomija ten ważny szczegół.
Hendeca

13
Chociaż to działa w JavaScript, nie wiem, dlaczego kiedykolwiek chciałbyś to zrobić. Odważam się przypuszczać, że większość programistów nie jest tego świadoma (w tym ja przed przeczytaniem tego), co, jak podejrzewam, szybko stałoby się problemem związanym z konserwacją wśród programistów. Czasami najbardziej sprytny sposób nie jest najlepszy.
Simon,

14
To jest okropne. Jeśli ktoś doda instrukcję i zapomni zamienić średnik w przecinek przed przedostatnią teraz instrukcją w bloku, masz błąd, który może być naprawdę trudny do wykrycia, ponieważ przecinek i średnik na końcu linii również wyglądają podobny.
Ingo Bürk

1
Wolę podejście „Hemingwaya” : bardzo czyste. I bez spacji między ifi (, jakif(true) doSomething();
victorf

8

Nie ma powodu programistycznego, aby używać nawiasów klamrowych w instrukcjach jednowierszowych.

Sprowadza się to tylko do preferencji programistów i czytelności.

Twój kod nie zepsuje się przez to.


7

Oprócz powodu wspomnianego przez @Josh K (który dotyczy również Java, C itp.), Jednym ze specjalnych problemów w JavaScript jest automatyczne wstawianie średników . Z przykładu z Wikipedii:

return
a + b;

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

Może to również przynieść nieoczekiwane rezultaty, jeśli zostanie użyte w ten sposób:

if (x)
   return
   a + b;

Nie jest o wiele lepiej pisać

if (x) {
   return
   a + b;
}

ale może tutaj błąd jest trochę łatwiejszy do wykrycia (?)


Wszystkie te przykłady wyglądają dla mnie okropnie, chyba że autorzy są tymczasowi i opłacani liniowo lub dopóki to nie zadziała.
Cees Timmerman


4

Jest wiele dobrych odpowiedzi, więc nie będę powtarzał, chyba że powiem moją „regułę”, kiedy można pominąć nawiasy klamrowe: na warunkach, które „zwracają” lub „rzucają” (np.) Jako jedyne stwierdzenie . W tym przypadku kontrola przepływu jest już jasna, że ​​się kończy:

Nawet „zły przypadek” można szybko zidentyfikować (i naprawić) dzięki końcowej kontroli przepływu. Ta „zasada” koncepcji / struktury dotyczy również wielu języków.

if (x)
    return y;
    always();

Oczywiście, dlatego też można użyć lintera.


3

Oto dlaczego jest to zalecane

Powiedzmy, że piszę

if(someVal)
    alert("True");

Potem przychodzi następny programista i mówi „Och, muszę zrobić coś innego”, więc piszą

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

Jak widać, „AlsoTrue” będzie zawsze prawdziwe, ponieważ pierwszy programista nie używał nawiasów klamrowych.


To nieprawda, brakuje „else”: if (someVal) alert („True”); else alert („AlsoTrue”); byłoby poprawne. Nie użyłbym tego, ponieważ podoba mi się {}, ponieważ jest o wiele lepiej czytelny.
Gerrit B

1
Co? Nie miałem innego oświadczenia. Mówiłem, że bez nawiasów klamrowych może to prowadzić do błędów, jeśli ktoś doda nową linię. Myślę, że nie zrozumiałeś mojego punktu widzenia.
Amir Raminfar

Myślę, że mówi, że druga linia zostanie wykonana bez względu na wszystko. Instrukcja If bez nawiasów klamrowych może wykonać tylko 1 wiersz.
PostCodeism

3

Obecnie pracuję nad minifikatorem. Nawet teraz sprawdzam to na dwóch ogromnych skryptach. Dowiedziałem się eksperymentalnie: Możesz usunąć nawiasy klamrowe za, jeśli, else, while, function *, jeśli nawiasy klamrowe nie zawierają znaków „;”, „return”, „for”, „if”, „else”, „podczas”, „do”, „funkcja”. Niezależnie od łamania linii.

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

Oczywiście musisz zastąpić nawias zamykający średnikiem, jeśli nie następuje po nim w innym nawiasie zamykającym.

Funkcja nie może kończyć się przecinkiem.

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

Testowane na Chrome i FF.


2

Zawsze to znalazłem

if(valid) return;

jest łatwiejsze dla oka niż

if(valid) {
  return;
}

również warunkowe, takie jak

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

są bardziej czytelne (moja osobista opinia) niż

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

ale myślę, że sprowadza się to do stylu kodowania


2

Nie odpowiadam na pytanie bezpośrednio, ale poniżej znajduje się krótka składnia dotycząca warunku warunkowego w jednym wierszu

Dawny:

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

Można zapisać w ten sposób:

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


1

Znalazłem tę odpowiedź, szukając podobnego doświadczenia, więc postanowiłem odpowiedzieć na nią moim doświadczeniem.

Instrukcje bez nawiasów działają w większości przeglądarek, jednak przetestowałem, że metody bez nawiasów w rzeczywistości nie działają w niektórych przeglądarkach.

Od 26 lutego 2018 roku to oświadczenie działa w Pale Moon, ale nie w Google Chrome.

function foo()
   return bar;

0

Początkowy poziom wcięcia instrukcji powinien być równy liczbie otwartych nawiasów klamrowych nad nią. (z wyłączeniem nawiasów klamrowych z cytatami lub komentarzami lub w dyrektywach preprocesora)

W przeciwnym razie K&R byłby dobrym stylem wcięcia. Aby poprawić ich styl, zalecam umieszczenie krótkich prostych zdań if w jednej linii.

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

zamiast

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

Gdybym pisał edytor, sprawiłbym, że przycisk automatycznego formatowania zasysał pasek do tej samej linii co foo i wstawił nawiasy klamrowe dookoła paska, jeśli wciśniesz przed nim powrót w następujący sposób:

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

Wtedy łatwo i spójnie dodać nowe instrukcje powyżej lub poniżej paska w treści instrukcji if

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

-1

Czasami wydają się potrzebne! Sam nie mogłem w to uwierzyć, ale wczoraj przyszło mi do głowy podczas sesji Firebuga (ostatnio Firefox 22.0)

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

wykonane, zrób coś, mimo że mój.condition.key był prawdziwy . Dodawanie szelek:

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

naprawił tę sprawę. Są miriady przykładów, gdzie najwyraźniej działa bez aparatu ortodontycznego, ale w tym przypadku na pewno nie.

Ludzie, którzy mają tendencję do umieszczania więcej niż jednego stwierdzenia w wierszu, powinni zdecydowanie zawsze używać nawiasów klamrowych, ponieważ takie rzeczy lubią

if (condition)
    do something; do something else;

są trudne do znalezienia.


Ciekaw jestem, w jakim scenariuszu brak szelek sprawił, że warunek if był prawdziwy, czy możesz sobie przypomnieć lub podać prawdziwy przykład?
gitsitgo,

Wyrażenie warunkowe jest zawsze oceniane przed instrukcją. Jestem również bardzo ciekawy, aby zobaczyć prawdziwy przykład tego, ponieważ oznaczałoby to błąd w tłumaczu.
Średnik

-1

Chciałbym tylko zauważyć, że możesz również pozostawić aparat ortodontyczny poza pozostałymi. Jak widać w tym artykule Johna Resiga .

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

[Styl nawiasów Qt] [1] wymaga bloków po obu stronach, elseaby dopasować użycie nawiasów - ten przykład wymagałby nawiasów klamrowych w elsebloku w celu przejścia przeglądu kodu. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgrease

Dlaczego głos przeciw? Powyższe stwierdzenie jest w 100% trafne.
Johnston

-1

Istnieje sposób na uzyskanie wielu wierszy, nie zawierających nawiasów klamrowych, jeśli instrukcje ... (Wow, jaki angielski ...), ale jest to trochę tedius:

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


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

Nie musisz mieć tylu nowych linii, pomijając nawiasy klamrowe. Powyższe można również zapisać w dwóch wierszach jako: if (true) funcName()i else return null
phobos
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.