rai*_*7ow 34

它打印此表达式的结果 - 即undefined.是的,var a它本身就是一个有效的表达方式.

实际上,当你写作或类似的东西时,你应该为什么console打印而感到好笑.它还会打印if 语句.实际上,如果有另一个带有"真实"结果的语句,那么所有和声明(!)语句似乎都会被忽略:undefinedvar a = 3undefinedfunction anyFunctionName() {}varfunction

>>> var a = 3;
undefined

>>> var a = 3; a = 4;
4

>>> var a = 3; a = 4; var a = 5; function f() {};
4 // !!!
Run Code Online (Sandbox Code Playgroud)

现在,我想背后的真正原因是行为的eval语句,描述在这里:

  • 让我们result评估该计划的结果prog.
  • 如果result.type是,normal并且其完成值是a value V,则返回value V.
  • 如果result.typenormal和它的完成值是empty,则返回该值undefined.

所以现在的问题是,var a = 4语句会返回什么?猜猜看:它不是4.

生产VariableStatement:var VariableDeclarationList; 评估如下:

  • 评估VariableDeclarationList.
  • 返回(正常,空,空).

现在最有趣的部分:在最后一个例子中发生了什么,为什么4是结果?本节对此进行解释:

生产程序:SourceElements的评估如下:

  • 让结果成为评估SourceElements的结果.

[...]

生产SourceElements:SourceElements*SourceElement*的计算方法如下:

  • 让headResult成为评估SourceElements的结果.
  • 如果headResult突然完成,则返回headResult.
  • 让tailResult成为评估SourceElement的结果.
  • 如果tailResult.value为空,则让V = headResult.value,否则让V => tailResult.value.
  • 返回(tailResult.type,V,tailResult.target)

两个function f() {}var a = 5 语句的返回值都是(normal, empty, empty).因此,脚本最终给出了第一个语句的结果(从脚本的结尾开始,技术上它是最后一个),但事实并非如此(normal, empty, empty).这是a = 4赋值语句的结果- 即4.


PS现在有点锦上添花:考虑以下几点:

>>> function f() {}
undefined

>>> (function f() {})
function f() {}
Run Code Online (Sandbox Code Playgroud)

差异非常微妙:第一个输入被视为一个Function Declaration声明,根据此规则......

生产SourceElement:FunctionDeclaration的计算方法如下:

  • 返回(正常,空,空).

......最终将产生undefinedeval-ed,因为我们已经知道了.

但是,第二个输入被视为a Function Expression,它被评估为函数本身.这意味着它将被传递eval并最终返回到控制台(以其格式).


csh*_*aml 5

var a=1;
a
Run Code Online (Sandbox Code Playgroud)

给出:

1
Run Code Online (Sandbox Code Playgroud)

var a=1;
Run Code Online (Sandbox Code Playgroud)

给出:

undefined
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,控制台会评估a,因此会输出a的值

在第二种情况下,控制台不评估a的值,但评估表达式本身。