为什么控制台上的JavaScript变量声明导致“未定义”被打印?

时间:2014-04-03 17:29:10

标签: javascript

我已阅读以下SO帖子:

Why does this JavaScript code print “undefined” on the console?

Why does Chrome & FireFox console print undefined?

Why does the JS console return an extra undefined?

但是,当我按如下方式声明变量时,没有一个能解释为什么JavaScript控制台会打印 undefined

var a;

4 个答案:

答案 0 :(得分:32)

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

实际上,当您编写console或类似内容时,您应该对undefined打印var a = 3的原因感到好笑。如果处理undefined语句,它还会打印function anyFunctionName() {}。实际上,如果有另一个带有“真实”结果的语句,那么所有varfunction声明(!)语句似乎都会被忽略:

>>> var a = 3;
undefined

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

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

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

  
      
  • result成为评估计划prog的结果。
  •   
  • 如果result.typenormal且其完成值为value V,则返回value V
  •   
  • 如果result.typenormal且其完成值为empty,则返回值undefined
  •   

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

  

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

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

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

  

制作计划 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


P.S。现在,为了一些锦上添花:考虑以下几点:

>>> function f() {}
undefined

>>> (function f() {})
function f() {}

区别非常微妙:第一个输入被视为Function Declaration语句,根据此规则......

  

生产 SourceElement FunctionDeclaration 评估为   如下:

     
      
  • 返回(正常,空,空)。
  •   
正如我们已经知道的那样,

...最终会产生undefined eval

然而,第二个输入被视为Function Expression,其被评估为to the function itself。这意味着它将通过eval传递并最终返回到控制台(格式)。

答案 1 :(得分:3)

因为你所做的只是声明有一个变量 - 它是什么?字符串,整数,布尔值 - 我们还不知道 - 因此undefined

答案 2 :(得分:3)

var a=1;
a

给出:

1

,而

var a=1;

给出:

undefined

在第一种情况下,控制台评估a,因此它打印了

的值

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

答案 3 :(得分:0)

每次评估一行代码时,您都会得到一个完成类型/记录 dumps,它具有 3 个属性:import requests import json with open("myfile.txt", "w") as output: resp = requests.get("https://jsonplaceholder.typicode.com/todos/1") output.write(json.dumps(resp.json())) resulttype。根据{{​​3}}:

<块引用>

如果 value 是正常的并且它的完成值为值 target,则返回值 result.type

<块引用>

如果 V 是正常的并且其完成值为 V,则返回值 result.type

事实证明,当您声明变量或函数时,emptyundefined。由于 completion type(normal,empty,empty) 且值为 result.type,因此它返回值 normal

但是,当您键入 empty 时,它是一个赋值表达式,其完成类型为 undefined。因此,您只会在控制台中看到 a = 3

有关 (normal, GetValue(), empty)3 的术语,请参阅 Ecma specification

对于不同的完成类型值,请参见difference statement/expression

如果您查看完成类型文档,您可以看到空语句 statement 也有一个完成类型 expression(因此它应该返回 ;),确实如此。出于同样的原因,(normal, empty, empty) 也返回 undefinedif (x>3) {console.log(x)}

但是,undefined 不返回 do {console.log(3);} while (false),因为它是一个表达式语句。

自行测试。以下是更多示例:

(function f(){})