Javascript提升和变量赋值(没有声明)

Vev*_*rke -1 javascript hoisting

查看MDN对JavaScript,语法和类型部分的介绍 - 一篇内容如下:

声明变量

您可以通过三种方式声明变量:

  • 使用关键字var.例如,var x = 42.此语法可用于声明局部变量和全局变量.
  • 只需为其分配一个值即可.例如,x = 42.这总是声明一个全局变量.它会生成严格的JavaScript警告.你不应该使用这个变种.
  • 使用关键字let.例如,设y = 13.此语法可用于声明块范围局部变量.请参阅下面的变量范围

以下代码片段似乎适合"通过简单地为其赋值"方案,这意味着该变量应被视为全局变量.

(function(){
   console.log(myVar);
   //the following will throw a ReferenceException error
   //myVar = 10;

   //the following will not, and I can understand it following the defintion of the behavior of using `var` keyword
   //var myVar = 10;
})();
Run Code Online (Sandbox Code Playgroud)

但是,运行代码将在myVar注释时生成ReferenceException ,而在未注释时生成undefined.我希望它在两种情况下都生成未定义,因为if myVar是一个全局变量(根据定义),而不是javascript的变量提升会在到达之前使其知道console.log(myVar);

这种行为背后的解释是什么?(我描述的行为是我在firefox的控制台中尝试时得到的,但运行它jsfiddle不会引发错误).

自动执行功能是吊装的例外吗?

Que*_*tin 7

"通过简单地赋予它一个值"的场景

您正在阅读该值,而不是分配它

如果myVar是一个全局变量(根据定义),

事实并非如此.

myVar 是:

  • 可变范围限定于功能如果函数包含var myVar(或function myVar () { ... },或它被列为在函数定义的参数).
  • 如果块包含,则作用于块的变量let myVar
  • 如果先前已为其分配了值,并且上述条件都不为真,则为全局变量.

由于您尚未分配值,因此它不是全局值.由于以上条件均不属实,因此它不是任何类型的变量,因此您会收到引用错误.


关于你的评论:

当我想在我试图描绘的场景中使用var时,我离开了我的var.更新的问题.

...以及您引用的编辑:

注释掉的代码不会被评估.拥有使用该关键字的评论var不会做任何事情.


关于您的进一步编辑.

如果在声明变量之前尝试读取变量,则会出现引用错误.

var 语句(和函数声明)被提升,因此使用这些方法声明的变量可以在函数中的任何位置读取.

作业未被吊销.通过赋值隐式创建的全局变量(通常不被认为是最佳实践并且在严格模式下被禁止)在分配值之前无法读取.