Подтвердить что ты не робот

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

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

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

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

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

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

Firebug:

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

Node.js

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

4b9b3361

Ответ 1

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

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

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

Block :
    { StatementList(opt) }

StatementList :
    Statement
    StatementList Statement

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

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

Изменить: если вы хотите, вы можете увидеть его в исходном коде двигателя JavaScript:

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

Ответ 2

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

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

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

foo({});

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

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