Чи потрібні дужки в однорядкових операторах у JavaScript?


163

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

Чи є щось, що робить гарною ідеєю оточити всі заяви у фігурних дужках у JavaScript?

Я прошу, бо всі, здається, так роблять.


5
Примітка: лише перше твердження передбачає обсяг, навіть якщо у вас є кілька висловлювань на одному рядку, тож це не «однорядкові висловлювання», а скоріше одне твердження
Кріс Іванов,

1
Можливо, ви думаєте про питання, описане в цій відповіді
Блоргберд вийшов

@Blorgbeard: ні, я насправді відповів на цю відповідь ще тоді.
Вежа

Так, я бачу.
Незважаючи на це

Ось ваша відповідь: medium.com/@jonathanabrams/…
Ерван Легранд,

Відповіді:


204

Немає

Але вони рекомендуються. Якщо ви коли-небудь розгорнете заяву, вони вам знадобляться.

Це цілком справедливо

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

Однак настійно рекомендується завжди використовувати дужки, тому що якщо ви (або хтось інший) коли-небудь розширює заяву, це буде потрібно.

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

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

28
+1, інформативна відповідь. Однак особисто мені ніколи не було корисно робити цю "рекомендовану" річ. Я ніколи не кодував пітона, тому не просто вставляв речі і очікую, що відступ має значення. Якщо я додаю заяву, я також додаю дужки. Завжди. Не можу пригадати жодного разу, як мене вкусило. Не в C, не в C # не в JavaScript.
Якоб

16
@Kirk: Дуглас Крокфорд рекомендує це. Я погоджуюся, що це особисте особисте рішення, але при роботі в групі легше просто набрати брекети.
Джош К

10
@ Джош, о, добре, Крокфорд сказав це. Це повинно бути заключним словом. ;) (просто жартує) Проблема полягає в тому, що суб'єктивність цього пункту поширюється на всі мови, подібні С, і сильні думки можна знайти в усьому (для обох позицій).
Кірк Волл

11
Мій особистий досвід показує, що нерозміщення брекетів може призвести до великих викручувань при роботі над командами.
панове

4
Добре застосовувати завжди брекети {}. Як казав @Arx, помилок, якщо ви їх не будете, набагато більше. У Apple навіть була помилка в SSL / TLS iOS, оскільки вони не використовували брекети
Keenan Lidral-Porter

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
Використання фігурної лівої дужки та фігурної правої дужки робить умови зрозумілими. Для мрійників серед нас, яких також називають лівим і правим літаючим птахом.
Півмісяця

61

Питання задає питання про твердження в одному рядку. Тим не менш, багато поданих прикладів показують причини не випускати дужки на основі декількох висловлювань рядків. Цілком безпечно не використовувати дужки в одному рядку, якщо це стиль кодування, який ви віддаєте перевагу.

Наприклад, питання задає, чи це нормально:

 if (condition) statement;

Це не питає, чи це нормально:

 if (condition)
   statement;

Я думаю, що залишати дужки кращим, оскільки це робить код більш читабельним із менш зайвим синтаксисом.

Мій стиль кодування - ніколи не використовувати дужки, якщо код не є блоком. І ніколи не використовувати кілька операторів в одному рядку (розділених крапками з комою). Я вважаю, що це легко читати і чітко, і у мене ніколи не виникає проблем із визначенням обсягу заяв "якщо". Як результат, використання дужок на одиничному, якщо оператор стану вимагає 3 рядки. Подобається це:

 if (condition) {
   statement;
 }

Використання одного рядка, якщо оператор є кращим, оскільки він використовує менше вертикального простору і код є більш компактним.

Я б не змушував інших використовувати цей метод, але він працює для мене, і я не міг більше не погодитися з наведеними прикладами того, як вивільнення дужок призводить до помилок кодування / визначення обсягу.


1
Я завжди відчував, що завжди слід включати брекети ... але я зараз переосмислюю це. У вас є керівництво зі стилю airbnb на вашому боці!
senderle

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

1
Додані 2 рядки для кожної дужки для оточення однорядкових висловлювань не є великою вартістю порівняно з потенційним збитком, який може спричинити - навіть дуже уважний розробник - підтримання вашого коду. Ви самі можете бути чудовим розробником з міфічними навичками, але не можете припустити, що це ваші колеги. KISS, оберніть речі контекстом і зробіть це максимально легким для інших, інакше з часом ви потрапите в біду.
Мацей Токарз

@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 є null, а b - null, ви отримуєте лише "error b", ви ніколи не отримуєте "error a".
racketsarefast

На ваших прикладах ваша команда розробників взагалі не знає, як кодувати, брекети їм не допоможуть ...
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;
}

але, можливо, тут помилку трохи простіше виявити (?)


Усі ці приклади для мене виглядають жахливими, якщо тільки письменники не є тимчасовими і не платять по рядку або поки це не працює.
Cees Timmerman


4

Є багато хороших відповідей, тому я не повторюсь, крім випадків, коли я можу сказати своє "правило", коли дужки можуть бути пропущені: за умов, які "повертаються" або "кидаються" (напр.) Як єдине твердження . У цьому випадку контролем потоку вже зрозуміло, що він закінчується:

Навіть «поганий випадок» може бути швидко ідентифікований (і зафіксований) через припинення контролю потоку. Це "правило" концепції / структури також застосовується до кількох мов.

if (x)
    return y;
    always();

Звичайно, це також, чому можна використовувати підводку ..


3

Ось чому це рекомендується

Скажімо, я пишу

if(someVal)
    alert("True");

Потім приходить наступний розробник і каже "Ой, мені потрібно щось інше зробити", тому вони пишуть

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

Тепер, як ви бачите, "ТакожTrue" завжди буде правдою, тому що перший розробник не використовував дужки.


Це не правильно, ви пропускаєте попередження 'else': якщо (someVal) попередження ("True"); else alert ("ТакожTrue"); було б правильно. Я б не користувався ним, тому що мені подобається {}, оскільки він набагато краще читається.
Герріт Б

1
Так? Іншої заяви у мене не було. Я говорив, що без фігурних дужок це може призвести до помилок, якщо хтось додасть новий рядок. Я думаю, ви не зрозуміли мою думку.
Амір Рамінфар

Я думаю, що він говорить, що 2-й рядок буде виконаний незалежно від того. Оператор If без дужок може виконати лише 1 рядок.
PostCodeism

3

Зараз я працюю над мініфікатором. Навіть зараз я перевіряю це на двох величезних сценаріях. Експериментально я з’ясував: Ви можете видалити фігурні дужки ззаду, якщо, інакше, поки функціонувати *, якщо фігурні дужки не включають ';', 'return', 'for', 'if', 'else', 'while', 'do', 'function'. Незалежно від розривів рядків.

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 (foo) bar();    // I like this. It's also consistent with Python FWIW

замість

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

Якби я писав редактор, я б змусив його кнопку автоматичного форматування висмоктати смужку до тієї ж лінії, що і foo, і я змусив би її вставити дужки навколо смуги, якщо натиснути клавішу return перед цим:

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, ви можете пригадати чи надати реальний приклад цього?
gitsitgo

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

-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
phobos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.