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

查看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;
    })();
    

    但是,运行代码会在myVar注释时生成ReferenceException,如果没有,则会生成未定义的代码。 我希望它在两种情况下都会生成未定义的,因为如果myVar是一个全局变量(每个定义),那么在达到console.log(myVar);之前,javascript的变量提升会使其知道console.log(myVar);

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

    自动执行功能是否是吊装的例外情况?


    “通过简单地分配一个值”场景

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

    如果myVar是全局变量(每个定义),

    事实并非如此。

    myVar是:

  • 如果函数包含var myVar (或function myVar () { ... } ,或者它在函数定义中作为参数列出function myVar () { ... }则该变量的作用域为该函数的作用域。
  • 如果块包含let myVar则将变量作用于该块
  • 一个全局变量,如果一个值已经被赋值给它并且上述条件都不成立。
  • 由于您尚未分配值,因此不是全局值。 由于上述条件都不是真的,它不是任何一种变量,所以你得到一个参考错误。


    关于你的评论:

    我在我想描述的场景中表示var时就离开了我的var。 更新的问题。

    ...以及您所参考的编辑:

    注释掉的代码不被评估。 使用关键字var的注释不会执行任何操作。


    关于你的进一步修改。

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

    var语句(和函数声明)被挂起,所以用这些方法声明的变量可以在函数的任何地方被读取。

    作业没有悬挂。 通过赋值隐式创建的全局变量(通常不被认为是最佳实践,并且在严格模式下被禁止)在指定值之前无法读取。


    由于我的评论似乎有助于向你解释,我会把它变成一个答案:

    隐式全局变量创建(当你没有实际声明它,但只是分配给它)不会被挂起。 变量创建在分配发生时内联发生。

    因此,当您尝试读取变量时,它不存在,这是一个错误。

    varlet声明被提升到适当范围的顶部。


    所有这些都应该有助于解释为什么你应该在strict模式下运行,其中隐式全局创建是非法的并且是不允许的并触发立即错误。 这基本上是邪恶的。 拼写错误的变量可能不会在您真正需要时触发错误。

    链接地址: http://www.djcxy.com/p/96305.html

    上一篇: Javascript hoisting and variable assignment (with no declaration)

    下一篇: Javascript updating global variables and hoisting