Нужны ли скобки в однострочных операторах в JavaScript?


163

Однажды я слышал, что оставлять фигурные скобки в однострочных операторах может быть вредно для JavaScript. Я больше не помню причины, и поиск в Google не сильно помог.

Есть ли что-нибудь, что делает хорошей идеей заключить все операторы в фигурные скобки в JavaScript?

Я спрашиваю, потому что все, кажется, делают это.


5
Примечание: только первый оператор принимает область видимости, даже если у вас есть несколько операторов в одной строке, так что это не «однострочные операторы», а скорее один оператор
Крис Иванов

1
Возможно, вы думаете о проблеме, описанной в этом ответе
Blorgbeard вышла

@Blorgbeard: нет, я действительно ответил на этот ответ некоторое время назад.
Башня

Ха, так я вижу. Не берите в голову тогда :)
Blorgbeard отсутствует

Ответы:


204

нет

Но они рекомендуются. Если вы когда-нибудь расширите утверждение, они вам понадобятся.

Это совершенно верно

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

Тем не менее, настоятельно рекомендуется всегда использовать фигурные скобки, потому что если вы (или кто-то еще) когда-либо расширяете утверждение, это будет необходимо.

Та же самая практика следует во всех языках стиля синтаксиса C с креплением. C, C ++, Java и даже PHP поддерживают оператор одной строки без фигурных скобок. Вы должны понимать, что вы сохраняете только двух персонажей, а с помощью бодрящих стилей некоторых людей вы даже не сохраняете строки. Я предпочитаю полный стиль скобок (как следует), поэтому он имеет тенденцию быть немного длиннее. Компромисс очень хорошо сочетается с тем фактом, что у вас предельно четкая читаемость кода.

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

28
+1, информативный ответ. Лично я никогда не считал полезным делать эту «рекомендованную» вещь. Я никогда не кодировал Python, поэтому я не просто вставляю вещи и ожидаю, что отступ будет иметь значение. Если я добавлю заявление, я также добавлю фигурные скобки. Всегда. Не могу вспомнить ни одного раза, когда это укусило меня. Не в C, не в C #, не в JavaScript.
Якоб

16
@Kirk: Дуглас Крокфорд рекомендует это. Я согласен, что это субъективное личное решение, но при работе в группе легче просто набрать скобки.
Джош К

10
@ Джош, ну, Крокфорд сказал это. Это должно быть последнее слово. ;) (шучу) Проблема в том, что субъективность этого пункта распространяется на все C-подобные языки, и во всем можно найти сильные мнения (для обеих позиций).
Кирк Волл

11
Мой личный опыт показывает, что не размещение браслетов может привести к большим ошибкам при работе в команде.
Господа

4
Рекомендуется всегда использовать фигурные скобки {}. Как сказал @Arx, есть гораздо больше места для ошибок, если вы их пропустите. У Apple даже была ошибка в iOS / SSL / TLS, потому что они не использовали фигурные скобки
Кинан Лидрал-Портер

94

Есть аспект читабельности - в том случае, когда у вас есть составные операторы, это может очень запутать. Отступ помогает, но ничего не значит для компилятора / интерпретатора.

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

И еще есть аспект расширяемости:

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

Мысль идет о том, что если у вас всегда есть скобки, то вы знаете, чтобы вставить другие операторы внутри этого блока.


4
Вот почему мы всегда должны использовать его как однострочник if (a===true) alert(a);. Теперь понятно!
Жоао Пиментел Феррейра

1
Использование фигурных левых скобок и фигурных правых скобок упрощает условия. Для мечтателей среди нас, также называемых левой и правой летящей птицей.
HalfMens

61

Вопрос спрашивает об утверждениях в одну строку. Тем не менее, многие приведенные примеры показывают причины не пропускать скобки, основанные на многострочных операторах. Совершенно безопасно не использовать скобки в одной строке, если вы предпочитаете такой стиль кодирования.

Например, вопрос спрашивает, нормально ли это:

 if (condition) statement;

Он не спрашивает, нормально ли это:

 if (condition)
   statement;

Я думаю, что оставить скобки предпочтительнее, потому что это делает код более читабельным с менее избыточным синтаксисом.

Мой стиль кодирования - никогда не использовать скобки, если код не является блоком. И никогда не использовать несколько операторов в одной строке (разделенных точкой с запятой). Я нахожу это легко читаемым и понятным, и у меня никогда не возникало проблем с формулировками «если». В результате, использование скобок для одного оператора условия потребует 3 строки. Как это:

 if (condition) {
   statement;
 }

Использование одной строки, если оператор предпочтительнее, потому что он использует меньше вертикального пространства и код более компактен.

Я бы не заставлял других использовать этот метод, но он работает для меня, и я не мог не согласиться с приведенными примерами того, как отсутствие скобок приводит к ошибкам кодирования / определения области видимости.


1
Я всегда чувствовал, что нужно всегда включать фигурные скобки ... но я переосмысливаю это сейчас. У вас есть руководство по стилю airbnb на вашей стороне!
Senderle

1
И все же вы забываете, что большинство форматеров кода изменяют его на двухстрочный формат, и вы возвращаетесь к проблемному коду. Аргумент вертикального пространства просто глуп. Читаемость всегда выигрывает, а сегодняшние экраны огромны.
Ким

1
Две строки, добавленные для каждой скобки, чтобы окружить ваши однострочные операторы, не являются большими затратами по сравнению с потенциальным ущербом, который может быть нанесен - даже очень осторожным разработчиком - поддержанием вашего кода. Вы сами можете быть отличным разработчиком с мифическими навыками, но вы не можете предполагать, что ваши коллеги. ПОЦЕЛУЙ, оберни вещи контекстом и сделай его как можно более легким для других, иначе у тебя будут неприятности.
Мацей Токарз

@senderle Правило eslint для управления этим может быть найдено здесь: eslint.org/docs/rules/curly#multi /*eslint curly: ["error", "multi"]*/
silkfire

15

Технически нет, но в остальном абсолютно Да !!!

Забудьте о «Это личные предпочтения», «код будет работать нормально», «он работал нормально для меня», «он более читабелен» yada yada BS. Это может легко привести к очень серьезным проблемам, если вы допустите ошибку и поверите мне, что очень легко допустить ошибку, когда вы кодируете (не верьте ?, посмотрите известную ошибку Apple, которая может потерпеть неудачу ).

Аргумент: «Это личное предпочтение»

Нет это не так. Если только вы не команда из одного человека, уезжающая на Марс, нет. Большую часть времени будут другие люди, читающие / изменяющие ваш код. В любой серьезной команде программистов это будет рекомендуемый способ, поэтому это не «личное предпочтение».

Аргумент: «код будет работать нормально»

Так же как и код спагетти! Означает ли это, что это нормально, чтобы создать его?

Аргумент: «у меня все работало нормально»

В моей карьере я видел очень много ошибок, созданных из-за этой проблемы. Вы, вероятно, не помните, сколько раз вы комментировали 'DoSomething()'и сбивали с толку, почему 'SomethingElse()'вызывается:

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

Или добавил SomethingMore и не заметил, что он не будет вызываться (хотя отступ подразумевает иное):

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

Вот пример из жизни, который у меня был. Кто-то хотел отключить ведение журнала, чтобы запустить поиск и замену "console.log"=> //"console.log":

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

Видишь проблему?

Даже если вы думаете, «это так тривиально, я бы никогда этого не сделал»; помните, что всегда будет член команды с более низкими навыками программирования, чем вы (надеюсь, вы не худший в команде!)

Аргумент: «это более читабельно»

Если я что-то узнал о программировании, так это то, что простые вещи очень быстро становятся очень сложными. Это очень часто, что это:

if (condition) 
    DoSomething();

превращается в следующее после того, как оно было протестировано с другими браузерами / средами / вариантами использования или добавлены новые функции:

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

И сравните это с этим:

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

PS: Бонусные баллы идут тому, кто заметил ошибку в приведенном выше примере.


2
хорошо очевидная ошибка - DoSomethingMore (); Но есть и другая ошибка. если a равно нулю, а b равно нулю, вы получите только «ошибку b», но никогда не получите «ошибку a».
Ракеты отправляются

По вашим примерам ваша команда разработчиков вообще не умеет кодировать, скобки им не помогут ...
Carlos ABS

некоторые примеры взяты из команды разработчиков Apple
Caner

13

Нет проблем с ремонтопригодностью!

Проблема со всеми вами в том, что вы ставите точки с запятой везде. Вам не нужны фигурные скобки для нескольких утверждений. Если вы хотите добавить заявление, просто используйте запятые.

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

Это правильный код, который будет работать так, как вы ожидаете!


2
Вы имеете в виду if, elseи , alertа не If, Elseа Alert?
Аниш Гупта

Вау, я этого не знал, спасибо, что сообщили мне! Кажется, большинство людей не учитывают эту важную деталь.
Хендека

13
Хотя это работает в JavaScript, я не могу понять, почему вы захотите это сделать. Я рискну предположить, что большинство разработчиков не знают об этом (включая меня, прежде чем читать это), что, как я подозреваю, могло бы быстро стать проблемой поддерживаемости среди разработчиков. Иногда самый умный путь не самый лучший.
Саймон

14
Это ужасно Если кто-то добавляет оператор и забывает превратить точку с запятой в запятую в текущем втором в последнем выражении в блоке, у вас есть ошибка, которую очень трудно обнаружить, потому что запятая и точка с запятой в конце строки выглядят слишком аналогичный.
Инго Бюрк

1
Я предпочитаю «хемингуэйский» подход : очень чистый. И без пробела между ifи (, вроде быif(true) doSomething();
victorf

8

Нет необходимости программировать использование фигурных скобок в одной строке.

Это сводится только к предпочтениям кодеров и удобочитаемости.

Ваш код не сломается из-за этого.


7

В дополнение к причине, упомянутой @Josh K (которая также относится к Java, C и т. Д.), Одной из особых проблем в JavaScript является автоматическая вставка точек с запятой . Из примера Википедии:

return
a + b;

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

Таким образом, это также может привести к неожиданным результатам, если использовать его так:

if (x)
   return
   a + b;

Не намного лучше написать

if (x) {
   return
   a + b;
}

но, может быть, здесь немного легче обнаружить ошибку (?)


Все эти примеры кажутся мне ужасными, если только авторы не являются временными и оплачиваются по линии или пока это не работает.
Сис Тиммерман


4

Есть много хороших ответов, поэтому я не буду повторяться, за исключением того, чтобы сказать мое «правило», когда фигурные скобки могут быть опущены: при условии, что «возврат» или «выброс» (например,) в качестве их единственного утверждения . В этом случае управление потоком уже ясно, что оно заканчивается:

Даже «плохой случай» может быть быстро идентифицирован (и устранен) благодаря прекращению управления потоком. Это понятие / структура «правило» также относится к ряду языков.

if (x)
    return y;
    always();

Конечно, именно поэтому можно использовать линтер.


3

Вот почему это рекомендуется

Допустим я пишу

if(someVal)
    alert("True");

Затем приходит следующий разработчик и говорит: «О, мне нужно сделать что-то еще», поэтому они пишут

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

Теперь, как вы видите, «Always» также всегда будет верным, потому что первый разработчик не использовал фигурные скобки.


Это не правильно, вы пропускаете 'else': if (someVal) alert ("True"); остальное предупреждение ("Кроме того") было бы правильно. Я бы не стал его использовать, потому что мне нравится {}, потому что он гораздо лучше читается.
Геррит Б

1
А? У меня не было другого заявления. Я говорил, что без фигурных скобок это может привести к ошибкам, если кто-то добавит новую строку. Я думаю, вы не поняли мою точку зрения.
Амир Раминфар

Я думаю, что он говорит, что 2-я строка будет выполнена, несмотря ни на что. Оператор If без фигурных скобок может выполнять только 1 строку.
PostCodeism

3

В настоящее время я работаю над миниатором. Даже сейчас я проверяю это на двух огромных сценариях. Экспериментально я выяснил: вы можете удалить фигурные скобки позади для if, else, while, функции *, если фигурные скобки не содержат ';', 'return', 'for', 'if', 'else', «а», «делать», «функция». Независимо от переноса строки.

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

Конечно, вам нужно заменить закрывающую скобку точкой с запятой, если за ней нет другой закрывающей скобки.

Функция не должна заканчиваться запятой.

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

Проверено на Chrome и FF.


2

Всегда находил, что

if(valid) return;

легче на мой взгляд, чем

if(valid) {
  return;
}

также условно, такие как

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

легче читать (мое личное мнение), чем

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

но я думаю, что все сводится к стилю кодирования


2

Непосредственно не отвечая на вопрос, но ниже приведен краткий синтаксис, если условие в одной строке

Пример:

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

Можно написать так:

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


1

Я нашел этот ответ в поисках аналогичного опыта, поэтому решил ответить на него своим опытом.

Операторы без скобок работают в большинстве браузеров, однако я проверял, что методы без скобок фактически не работают в некоторых браузерах.

По состоянию на 26 февраля 2018 года это утверждение работает в Pale Moon, но не в Google Chrome.

function foo()
   return bar;

0

Начальный уровень отступа оператора должен быть равен количеству открытых скобок над ним. (за исключением скобок в кавычках или в комментариях или в директивах препроцессора)

В противном случае K & R будет хорошим стилем отступов. Чтобы исправить их стиль, я рекомендую помещать короткие простые операторы if в одну строку.

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

вместо того

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

Если бы я писал редактор, я бы сделал так, чтобы кнопка его автоматического форматирования соскабливала строку до той же строки, что и foo, и я бы заставляла ее вставлять фигурные скобки вокруг бара, если вы нажимаете клавишу возврата перед этим следующим образом:

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

Тогда легко и последовательно добавлять новые операторы выше или ниже бара в теле оператора if

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

-1

Иногда они кажутся необходимыми! Я сам не мог в это поверить, но вчера мне пришло в голову сеанс Firebug (недавний Firefox 22.0), который

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

выполнено, сделать что-то, несмотря на то, что my.condition.key было правдой . Добавление брекетов:

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

исправил это дело. Есть множество примеров, когда это, очевидно, работает без скобок, но в этом случае это определенно не работает.

Люди, которые склонны помещать более одного утверждения в строку, должны, безусловно, всегда использовать фигурные скобки, потому что такие вещи, как

if (condition)
    do something; do something else;

трудно найти.


Мне любопытно, в каком сценарии отсутствие скобок сделало условие if верным, вы можете вспомнить или привести реальный пример этого?
Гитситго

Условное выражение всегда вычисляется перед оператором. Мне также очень любопытно увидеть реальный пример этого, потому что это представляет ошибку в интерпретаторе.
точка с запятой

-1

Я просто хотел бы отметить, что вы также можете оставить фигурные скобки от всего остального. Как видно из этой статьи Джона Резига .

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

[Стиль Qt фигурных скобок] [1] требует наличия блоков по обе стороны от него, elseчтобы соответствовать использованию фигурных скобок - в этом примере для подтверждения elseпроверки кода потребуются фигурные скобки на блоке. [1]: wiki.qt.io/Qt_Coding_Style#Braces
pixelgrease

Почему отрицательный голос? Заявление выше на 100% точно.
Джонстон

-1

Есть способ получить многострочные не фигурные скобки, если операторы .. (Вау, что по-английски ..), но это своего рода tedius:

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


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

Вам не нужно иметь так много новых строк, если пропустить фигурные скобки. Выше также можно записать в две строки: if (true) funcName()и else return null
Фобос
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.