为什么在控制台的JavaScriptvariables声明导致“undefined”被打印?

我已经阅读了以下SOpost:

为什么这个JavaScript代码在控制台上显示“undefined”?

为什么Chrome和FireFox控制台不能打印?

为什么JS控制台返回一个额外的未定义?

但是没有一个解释了为什么当我声明一个variables的时候,JavaScript控制台打印的时候没有定义如下:

var a;

它打印这个expression式的结果 – 这是undefined 。 是的, var a是一个有效的expression式。

实际上,当你写var a = 3东西的时候,你应该为什么console打印undefined而感到好笑。 如果function anyFunctionName() {}语句被处理,它也打印undefined 。 实际上,如果有另外一个带有“真实”结果的语句,那么所有的varfunction声明(!)语句都会被忽略:

 >>> var a = 3; undefined >>> var a = 3; a = 4; 4 >>> var a = 3; a = 4; var a = 5; function f() {}; 4 // !!! 

现在,我想背后的真正原因是eval语句的行为,如下所述:

  • result成为评估程序的结果。
  • 如果result.typenormal并且其完成值是一个value V ,则返回value V
  • 如果result.type normal且其完成值为empty ,则返回undefined值。

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

生产VariableStatementvar VariableDeclarationList; 评估如下:

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

现在最有趣的部分是:在最后一个例子中发生了什么,为什么4是结果呢? 这部分解释了这一点 :

生产计划SourceElements评估如下:

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

[…]

生产SourceElementsSourceElements * 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() {} 

区别是相当微妙的:第一个input被视为一个Function Declaration语句,根据这个规则…

生产SourceElementFunctionDeclaration的计算方法如下:

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

正如我们已经知道的那样,最终会产生undefined eval

然而,第二个input被视为一个Function Expression ,该Function Expression 对函数本身进行求值。 这意味着它将通过eval传递并最终返回到控制台(以其格式)。

因为你所做的只是声明有一个variables – 这是什么? 一个string,一个整数,一个布尔值 – 我们还不知道 – 因此undefined

 var a=1; a 

得到:

 1 

 var a=1; 

得到:

 undefined 

在第一种情况下控制台评估一个,所以它打印一个值

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