Search code examples
javascriptnode.jsundefinedread-eval-print-loopvariable-declaration

Mac terminal node REPL output for variable declarations


In the Mac (OS X 10.13.3) terminal, when I enter the REPL for node (v8.10.0) and enter the following various lines I get the indicated outputs:

> let a = 'abc'
undefined

> const b = 'abc'
undefined

> var c = 'abc'
undefined

> d = 'abc'
'abc'

Why the difference in output between the first three versus the last one?

I understand that, in ES5 non-strict mode, var x = 1 and x = 1 result in different variable scopes, but I suspect that's not the issue here.

I also understand that d = 'abc' is no longer a best practice for JavaScript and is not even allowed in, say, ES5 strict mode. However, I'm just trying to understand either the syntactic differences between the lines and/or how the node REPL interprets input. Does this have something to do with statements versus expressions (or definitions or assignments or declarations or...)?

(I've tried to search StackOverflow, but haven't found the answer in questions entitled 'node.js displays “undefined” on the console' or 'node.js REPL “undefined” '. I also can't find an answer in the Node.js v8.10.0 Documentation section for REPL. Searching Google for, say, node repl "return value", etc. also does not help.)


Solution

  • tl;dr

    The first two (let and const) are LexicalDeclarations. The next (var) is a VariableStatement. The last is an AssignmentExpression.

    LexicalDeclarations and VariableStatements have no return value. AssignmentExpressions have. Details below.


    Details

    Beginning with the third, take the var identifier = expression, for instance. It is a VariableStatement. Its evaluation semantics are expressed in the spec as below:

    Semantics

    The production VariableStatement : var VariableDeclarationList ; is evaluated as follows:

    1. Evaluate VariableDeclarationList.
    2. Return (normal, empty, empty).

    Notice the emptys in the return of the expression. The same doesn't happen in assignments (see the Return part).

    About the let and const declarations, about their evaluation:

    13.3.1.4 Runtime Semantics: Evaluation

    LexicalDeclaration : LetOrConst BindingList ;

    1. Let next be the result of evaluating BindingList.
    2. ReturnIfAbrupt(next).
    3. Return NormalCompletion(empty).

    Again, empty (undefined) return on normal completion. (Abrupt happens when the variable has already been declared, for example.)


    The last one is an AssignmentExpression. It evaluates to (returns) a value. For instance, take its simplest form, Simple Assignment, evaluation specs:

    The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows:

      1. Let lref be the result of evaluating LeftHandSideExpression.
        ...
      1. Return rval.

    Notice the returning of a value.