В ECMAScript Language Specification есть такое понятие, как Block (стр. 86):
Syntax
Block : { StatementList_opt }
StatementList : Statement StatementList Statement
SemanticsThe production Block : { } is evaluated as follows:
1. Return (normal, empty, empty).The production Block : { StatementList } is evaluated as follows:
1. Return the result of evaluating StatementList.The production StatementList : Statement is evaluated as follows:
1. Let s be the result of evaluating Statement.
2. If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if no exception were thrown.)
3. Return s.The production StatementList : StatementList Statement is evaluated as follows:
1. Let sl be the result of evaluating StatementList.
2. If sl is an abrupt completion, return sl.
3. Let s be the result of evaluating Statement.
4. If an exception was thrown, return (throw, V, empty) where V is the exception. (Execution now proceeds as if no exception were thrown.)
5. If s.value is empty, let V = sl.value, otherwise let V = s.value.
6. Return (s.type, V, s.target).
Насколько я понял этот текст, результатом интерпретации выражения { foo(); bar(); 10 } будет 10. Когда пишу такое выражение в REPL-е хромиума или фаербага, то в ответ получаю 10, что совпадает с моим пониманием спецификации.
Вопросы:
1. Почему результатом интерпретации { foo(); bar(); 10 } + 1 является 1?
2. Можно получить результат интерпретации блока через eval: eval('{ foo(); bar(); 10 }') + 1 == 11. Можно ли как-нибудь без eval-а обойтись?
Если интересно, для чего мне это нужно: хочу исправить баг в библиотеке clojurejs. Из (alert (if true (do (alert) «boom») «bam»)) она генерирует alert((true ? alert(); «boom»; : «bam»)), что неправильно. Если бы что-то типа этого alert((true ? { alert(); «boom» } : «bam»)) парсилось и работало, то фикс был бы тривиальным.