Можно ли сказать мне причину этой определенной структуры синтаксиса
eval('(' + jsonString+ ')')
При парсинге json текста. Crockford говорит, что "Текст должен быть перенесен в parens, чтобы не спотыкаться неоднозначность в синтаксисе JavaScript". здесь. Что это означает?
Мы можем избежать его?
Неоднозначность синтаксиса, на которую ссылается Крокфорд, заключается в том, что если открытая фигурная скобка не встречается в контексте выражения, она будет распознана как блок, а не как начало объектного литерала.
Например:
{"foo": "bar"} // SyntaxError
Выдаст синтаксическую ошибку, потому что будет интерпретирован как блок, со строковым литералом "foo", и неожиданным использованием лексемы :
.
С другой стороны, круглые скобки, формально называемые оператором группировки, могут оценивать только выражения, поэтому у нас не будет никакой синтаксической двусмысленности, потому что блок можно ожидать только в контексте statement.
({"foo": "bar"})
Edit: @el.pescado задает интересный вопрос:
Не могли бы вы объяснить, почему eval('{}') не определен?
ECMAScript описывает внутренний тип для объяснения поведения утверждений, он называется Completion Specification Type.
Значения типа Completion - это тройки вида (type, value, target)
, где type
может быть normal
, break
, continue
, return
или throw
.
value
может быть любым значением языка или пустым
, а target
любым идентификатором или пустым
.
Пустой блок (продукция Блок : {}
) явно возвращает следующее завершение:
Return (normal, empty, empty).
Функция eval
после выполнения кода и выхода из вновь созданного контекста выполнения проверяет результат завершения оцененного кода, и в Шаге 7 мы видим, что undefined
явно возвращается, если тип завершения normal
и значение завершения empty
:
. ..
7- Если тип result.type нормальный, а значение завершения пустое, то вернуть значение undefined.
...
Объектный литерал должен быть обернут в круглые скобки, чтобы правильно оцениваться в контексте eval
и других контекстах:
eval('{}')
не определяется, например. тогда как eval('(' + '{}' + ')' )
оценивает Object.
Если вы попробуете это сделать в консоли, например: {"foo": "bar"}
, он бы выдал вам недопустимую метку. Оберните это выражение в круглые скобки, и оно станет корректным.
@el.pescado, строка после выполнения eval должна быть понятна javascript. Например, если вы присваиваете приведенную выше строку переменной следующим образом
eval(' var foo1 = {"foo" : "bar"}'); foo1.foo вернет bar
Итак, я предполагаю, что поскольку в javascript нет утверждения, начинающегося с "{", он выдает ошибку.