我已经阅读了以下SO帖子:
为什么这个JavaScript代码在控制台上打印"未定义"?
但是,当我声明变量时,它没有解释为什么JavaScript控制台打印未定义,如下所示:
var a;
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并且其完成值是avalue V,则返回value V.- 如果
result.type是normal和它的完成值是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的计算方法如下:
- 返回(正常,空,空).
......最终将产生undefined时eval-ed,因为我们已经知道了.
但是,第二个输入被视为a Function Expression,它被评估为函数本身.这意味着它将被传递eval并最终返回到控制台(以其格式).
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的值,但评估表达式本身。
| 归档时间: |
|
| 查看次数: |
15941 次 |
| 最近记录: |