Когда JS интерпретирует {} как пустой блок вместо пустого объекта?

Я читал ответ на этот вопрос (о видео "wat") и он сказал:

  1. {}+[]
    Это интерпретируется как пустой блок кода, унарный плюс и пустой массив. Первая часть ничего не делает, массив преобразуется в разделенную запятыми строку его элементов (пустая строка для пустого массива), затем в число (пустая строка преобразуется в 0), следовательно, 0.

в настоящее время я изучаю JS из "окончательного руководства", поэтому я пытаюсь чтобы понять такие вещи.

мой вопрос в том, когда JS решает интерпретировать {} как пустой блок кода, а не пустой объект?

кроме того, существуют некоторые несоответствия между узлами.js и Firebug, которые я хотел бы понять.

Firebug:

Firebug console output for <code>{}[]</code> and <code>({}[])</code>

узел.js:

Node.js output for <code>{}[]</code> and <code>({}[])</code>

2 ответов


давайте посмотрим на грамматику языка, не так ли? Раздел 12, Заявления:

Statement :
    Block
    VariableStatement
    EmptyStatement
    ExpressionStatement
    ...lots of other stuff...

это очень причудливый способ сказать, что оператор может быть блоком, оператором переменной, пустым оператором, оператором выражения или множеством других вещей. Обратите внимание, что в первом варианте есть "блок":

Block :
    { StatementList(opt) }

StatementList :
    Statement
    StatementList Statement

что опять же, причудливый способ сказать, что блок-это {, необязательно с кучей операторов, за которыми следует }.

и это то, что вы видите в своем примере: прежде чем парсер JavaScript подумает, что у вас может быть объектный литерал (который определен где-то под ExpressionStatement, 4-я вещь "заявление" может быть), он сначала думает, что у вас есть "блок".

Edit: если вы хотите, вы можете увидеть его в прямом эфире в исходном коде движка JavaScript:

Что касается вашего второго вопроса, это было охвачено до мельчайших деталей по этому вопросу. Резюмировать в предложении: Node.js обрабатывает ваш ввод, как если бы он был выражение (таким образом, оно не может быть "блоком"), в то время как инструменты Firebug/Chrome dev рассматривают его как "оператор".


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

(на самом деле конечно, когда { появляется после предложения заголовка чего-то вроде if или while, потом {} тоже пустой блок, но это не интересные случае.)

таким образом, в любом другом контексте, например, скажем аргумент функции:

foo({});

на {} интерпретируется как пустой объект буквальный.

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