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


119

Чому фрагменти коду нижче, взяті з цієї статті , дають різні результати завдяки лише одній зміні розміщення фігурних дужок?

Коли вступна фігурна дужка {знаходиться на новому рядку, test()повертається undefined, а в повідомленні відображається "ні - вона зламалася: невизначено".

function test()
{
  return
  { /* <--- curly brace on new line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}

Коли дужка знаходиться на тій же лінії, що і return, test()повертає об'єкт, і "фантастичний" повідомляється.

function test()
{
  return { /* <---- curly brace on same line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}


семантика напіввставки після returnцього дещо відрізняється, ніж в інших місцях, а розрив рядка "означає більше" у цьому місці, ніж це було б "середній потік"
dandavis

Відповіді:


165

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

function test()
{
  return; // <- notice the inserted semicolon
  { 
    javascript: "fantastic"
  };
}

Дивіться також посібник із стилю JS Дугласа Крокфорда , де згадується вставка крапки з комою.

У другому прикладі ви повертаєте об'єкт (побудований фігурними дужками) із властивістю javascriptта його значенням "fantastic", фактично таким же, як цей:

function test() {
    var myObject = new Object();
    myObject.javascript = "fantastic";
    return myObject;
}

5
Факт веселощів: на деяких двигунах ви можете коментувати автоматично вставлені крапки з комою
Крістофер Таркіні

1
@ChrisT: Що? Котрий? Це десь досліджено?
Шон Макміллан

1
@SeanMcMillan Я точно читав статті про це, але я не можу знайти жодну з них у швидкому пошуку. Я пам’ятаю, що введення return /*та згодом */{ було б ефективно коментувати приховані напівкрапки у старих версіях хрому. Не впевнений, чи все-таки це стосується
Крістофер Таркіні

2
Через ці химерності я пообіцяв собі 10 років тому: тримайтеся подалі від Інтернету! Я молився, щоб Інтервебс згасав ... На жаль, це не пішло так, як планувалося, і зараз мені доводиться боротися і з цими питаннями. Karma ab * tch :)
Jowen

1
Я бачив людей, які релігійно протиступають крапкам з комою в JavaScript, мені завжди було цікаво, що вони роблять із тим додатковим часом, який вони економить, не кладучи крапки з комою.
Іман Мохамаді

9

Javascript не вимагає крапки з комою в кінці висловлювань, але недолік полягає в тому, що він повинен здогадуватися, де знаходиться крапка з комою. У більшості випадків це не проблема, але іноді вона видумує крапку з комою, де ви її не мали наміру.

Приклад з моєї публікації в блозі про це ( Javascript - майже не на основі рядка ):

Якщо ви форматуєте такий код:

function getAnswer() {
   var answer = 42;
   return
      answer;
}

Тоді це трактується так:

function getAnswer() {
  var answer = 42;
  return;
  answer;
}

Оператор return приймає свою параметричну форму, і аргумент стає власним твердженням.

Те саме відбувається і з вашим кодом. Функція інтерпретується як:

function test()
{
  return;
  {
    javascript : "fantastic"
  };
}

3

Я особисто віддаю перевагу стилю Allman для читабельності (проти стилю K&R).

Замість…

function test() {
  return {
    javascript : "fantastic"
  };
}

Мені подобається…

function test() 
{
  var obj =
  {
    javascript : "fantastic"
  };

  return obj;
}

Але це обхід. Я можу з цим жити.


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

1
Я вважаю його код читабельнішим, ніж K&R. Досить суб’єктивно, коли ви маєте на увазі "читабельний"
Бран

Я теж віддаю перевагу Allman ... але через ASI, коли мені потрібно повернути об'єкт, я залишаю напівписок на тій же лінії, що і повернення. Я вважаю за краще це, ніж додавати один рядок "var x =" ...
Мік

1

Це тому, що JavaScript найчастіше ставить ";" в кінці кожного рядка, так що, коли ви повертаєтеся {в тому ж рядку, javascript-движок бачить, що буде щось більше, а коли його в новому рядку, він вважає, що ви забули поставити ";", і ставить його вам.


1
Я не розумію, чому відповіді Чісі, Даріна та Іво були скасовані?
BoltClock

1

Кучеряві дужки тут вказують на побудову нового об’єкта. Таким чином ваш код еквівалентний:

function test() {
  var a = { javascript : "fantastic" };
  return a;
}

яка працює, якщо ви пишете:

function test() {
  var a = { javascript : "fantastic" };
  return; // ; is automatically inserted 
      a;
}

це більше не працює.


0

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


Так, я також читав це, ater Reading я прошу тут пояснити краще натхненником js.
JustLearn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.