'Assign result of block to a variable (gives SyntaxError)

If I open a Node REPL, and enter this code, I can see that it evaluates to 3:

$ node
> { let a = 1 + 2; a }
3
> 

However, this code does not work:

const result = { let a = 1 + 2; a };

I get this error:

const result = { let a = 1 + 2; a };
                     ^

SyntaxError: Unexpected identifier

What am I missing here? Am I correct in assuming that the block evaluates to the last expression within it, or is Node's REPL misleading me here?



Solution 1:[1]

As you've seen in the Node REPL, a block evaluates to a value, and that value is usually the value of the last statement in the block.

In ECMAScript 6.0, a BlockStatement is defined as follows (with subscripts omitted for simplicity):

BlockStatement:
    Block

Block:
    { StatementList }

StatementList:
    StatementListItem
    StatementList StatementListItem

StatementListItem:
    Statement
    Declaration

Per section 13.2.13, Note 2, "The value of a StatementList is the value of the last value producing item in the StatementList." A Block is evaluated to the value of its StatementList, and a BlockStatement is evaluated to the value of its Block.

Thus, Node is correctly evaluating your BlockStatement to the value of the last value producing item, which is a. This is not a bug, nor is it specific to Node.

The reason you are getting an error is because you are trying to use a BlockStatement in a context where it is not allowed.

const result = { let a = 1 + 2; a }; is a LexicalDeclaration, which is defined as follows (again, with subscripts omitted):

LexicalDeclaration:
    LetOrConst BindingList ;

LetOrConst :
    let
    const

BindingList:
    LexicalBinding
    BindingList , LexicalBinding

LexicalBinding:
    BindingIdentifier Initializer
    BindingPattern Initializer

We also need the definition of Initializer:

Initializer:
    = AssignmentExpression

As you can see, the part of your lexical declaration after the equal sign requires an AssignmentExpression. If you look through the grammar for expressions, you will see that BlockStatement is not an AssignmentExpression.

As of ES6.0, there is no way to use a BlockStatement direcly as an AssignmentExpression. However, if you want to evaluate one to an expression, you can use eval:

> const result = eval("{ let a = 1 + 2; a }");
> result
3

I don't recommend doing this under ordinary circumstances, but it is helpful for seeing how ES6.0 does indeed evaluate blocks to values.

Solution 2:[2]

In js braces represent an object which expects key: value pairs. You can get the result like this;

const result = {a: 1 + 2};
console.log(result.a);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Irfan wani