2016-09-22 5 views

ответ

2

Если вы не находитесь в контексте выражения (например, как показано на правой стороне присваивания), то {} является a block statement, а не литералом объекта.

0

Анализатор интерпретирует {} как кодовый блок. Вы можете сделать это разобрать правильно окружив скобки со скобками:

({}).toString(); 
1

{} захватывается первым и интерпретируется как блок, который не имеет .toString метод для вызова.

Если вы обертываете объект литералом в parens, например ({}).toString(), то он работает так, как ожидалось.

Это из-за приоритетов правила синтаксического анализа и токенов {}, перегружаемых как разделители объектов и блоков.

+0

@TJCrowder Исправлено (я работал над редактированием, но потерял просмотр спецификации :(). – ssube

+0

О, я никогда не делал этого ... ;-) –

3

what caused the difference?

состояние парсер. По умолчанию, анализатор находится в состоянии, в котором он ожидающей заявление. Итак, в вашем примере в консоли, { выглядит как открытие блока для него, а не начало инициализатора объекта. (Вы также можете дать ему выражение в этой точке, поскольку JavaScript имеет концепцию ExpressionStatement, что утверждение полностью состоящее из выражения.)

Но в вашем var a={}.toString(); коды {}.toString() появится справа -hand стороне ассистента, где синтаксический анализатор ожидает выражение , а не заявление. Таким образом, { запускает инициализатор объекта.

Если вы делаете что-то, чтобы сделать парсер ожидать выражение вместо этого, он будет работать в консоли тоже:.

({}).toString(); // "[object Object]" 

или

+{}.toString(); // NaN, because the `+` tries to turn `[object Object]` into a number and fails 
Смежные вопросы