Почему открывающая кавычка и скобка для eval ('(' + jsonString + ')') при разборе строки json - PullRequest
21 голосов
/ 29 июля 2010

Подскажите, пожалуйста, причину такой специфической синтаксической структуры

 eval('(' + jsonString+ ')')

При разборе текста в формате json.Крокфорд говорит: « Текст должен быть заключен в скобки, чтобы избежать путаницы в синтаксисе JavaScript ». здесь .Что это значит?

Можем ли мы избежать этого?

Ответы [ 3 ]

25 голосов
/ 29 июля 2010

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

Например:

{"foo": "bar"} // SyntaxError

Даст вам синтаксическую ошибку, потому что она будет интерпретироваться как блок, со строковым литералом "foo" и неожиданным использованием токена :.

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

({"foo": "bar"})

Редактировать: @el.pescado задает интересный вопрос:

Можете ли вы объяснить, почему eval ('{}') не определен?

ECMAScript описывает внутренний тип для объяснения поведения операторов, он называется Тип спецификации завершения .

Значения типа Завершение - это тройки вида (type, value, target), где type может быть normal, break, continue, return или throw.

value может быть любым значением языка или empty, а target любым идентификатором или empty.

Пустой блок (производство Block : {}) явно возвращает следующее завершение:

Return (normal, empty, empty).

Функция eval после выполнения кода и выхода из вновь созданного контекста выполнения проверяет завершение результата оцененного кода, и на шаге 7 мы видим, что undefined явно возвращается, если тип завершения normal и значение завершения empty:

...

7- Если result.type нормальный и его значение завершения пустое, вернуть значение undefined.

...

0 голосов
/ 01 августа 2010

@el.pescado, строка после выполнения eval должна быть понятной для javascript. т.е. если вы присваиваете вышеуказанную строку переменной, как показано ниже

eval ('var foo1 = {"foo": "bar"}'); foo1.foo вернет бар

Итак, я предполагаю, что нет такого утверждения, начинающегося с "{" в javascript, оно выдает ошибку.

0 голосов
/ 29 июля 2010

Литерал объекта должен быть заключен в скобки для правильной оценки в eval контексте и других контекстах:

Например,

eval('{}') не определено. тогда как eval('(' + '{}' + ')' ) оценивается как Object.

Если вы попробуете это в консоли, например: {"foo":"bar"}, вы получите неверный ярлык. Оберните его в скобки, и оно станет действительным выражением.

...