Почему результаты зависят от расположения фигурных скобок? - PullRequest
89 голосов
/ 04 сентября 2010

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

При открытии фигурных скобок { находится в новой строке, 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);
}

Ответы [ 6 ]

132 голосов
/ 04 сентября 2010

Это одна из ловушек JavaScript: автоматическая вставка точек с запятой.Строки, которые не заканчиваются точкой с запятой, но могут быть концом оператора, автоматически завершаются, поэтому ваш первый пример выглядит следующим образом:

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

См. Также Руководство по стилю JS Дугласа Крокфорда, в котором упоминается вставка точки с запятой.

Во втором примере вы возвращаете объект (построенный из фигурных скобок) со свойством javascript и его значением "fantastic", фактически таким же, как это:

function test() {
    var myObject = new Object();
    myObject.javascript = "fantastic";
    return myObject;
}
7 голосов
/ 04 сентября 2010

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

Пример из моего поста об этом блоге ( Javascript - почти не основан на строках ):

Если вы отформатируете код следующим образом:

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

Тогда это интерпретируется так:

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

Оператор return принимает форму без параметров, а аргумент становится собственным выражением.

То же самое происходит с вашим кодом. Функция интерпретируется как:

function test()
{
  return;
  {
    javascript : "fantastic"
  };
}
1 голос
/ 24 февраля 2012

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

Вместо ...

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

Мне нравится ...

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

  return obj;
}

Но этообходной путь.Я могу жить с этим, хотя.

1 голос
/ 04 сентября 2010

Здесь фигурные скобки указывают на строительство нового объекта.Таким образом, ваш код эквивалентен:

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

, который работает, тогда как если вы напишите:

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

, он больше не работает.

1 голос
/ 04 сентября 2010

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

0 голосов
/ 04 сентября 2010

Проблема действительно в инъекции точки с запятой, как описано выше.Я только что прочитал хорошую публикацию в блоге на эту тему.Это объясняет эту проблему и многое другое о JavaScript.Он также содержит несколько хороших ссылок.Вы можете прочитать это здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...