Mac 变量声明的终端节点 REPL 输出

Mac terminal node REPL output for variable declarations

在 Mac (OS X 10.13.3) 终端中,当我输入节点 (v8.10.0) 的 REPL 并输入以下各行时,我得到了指示的输出:

> let a = 'abc'
undefined

> const b = 'abc'
undefined

> var c = 'abc'
undefined

> d = 'abc'
'abc'

为什么前三个与最后一个之间的输出不同?

我知道,在 ES5 non-strict 模式下,var x = 1x = 1 会导致不同的变量范围,但我怀疑这不是这里的问题。

我也明白 d = 'abc' 不再是 JavaScript 的最佳实践,甚至不允许在 ES5 严格模式下使用。但是,我只是想了解节点 REPL 如何解释输入的 and/or 行之间的句法差异。这与语句与表达式(或定义或赋值或声明或...)有关吗?

(我尝试搜索 Whosebug,但没有在标题为 'node.js displays “undefined” on the console''node.js REPL“未定义”的问题中找到答案 '。我在 Node.js v8.10.0 Documentation section for REPL 中也找不到答案。在 Google 中搜索 node repl "return value" 等也无济于事。)

tl;博士

前两个(letconst)是LexicalDeclarations. The next (var) is a VariableStatement. The last is an AssignmentExpression

LexicalDeclarations 和 VariableStatements 没有 return 值。 AssignmentExpression有。详情如下。


详情

从第三个开始,以var identifier = expression为例。这是一个VariableStatement。它的评估语义在规范中表达如下:

Semantics

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

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

注意表达式 return 中的 empty。同样的事情不会发生在 assignments (see the Return part).

关于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).

同样,正常完成时为空 (undefined) return。 (例如,当变量已经被声明时突然发生。)


最后一张是AssignmentExpression. It evaluates to (returns) a value. For instance, take its simplest form, Simple Assignment,评价规格:

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

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

注意值的 returning。