【问题标题】:JavaScript 'hoisting' [duplicate]JavaScript \'提升\' [重复]
【发布时间】:2014-05-17 21:43:23
【问题描述】:

我遇到了 JavaScript \'hoisting\',但我没有弄清楚这段代码的 sn-p 是如何真正起作用的:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}

b();
alert(a);

我知道像 (function a() {}) 这样的函数声明将被提升到函数 b 范围的顶部,但它不应该覆盖 a 的值(因为函数声明会覆盖变量声明而不是变量初始化)所以我预计警报的值将是 10 而不是 1!

标签: javascript hoisting


【解决方案1】:
  1. 全局a 设置为1
  2. b() 被调用
  3. function a() {} 被提升并创建一个当地的变量 a 掩盖了全局 a
  4. 本地a设置为10(覆盖函数a
  5. 全球a(仍为1)收到警报

【讨论】:

  • 谢谢@Quentin我错过了事实3(该函数a(){}创建了一个掩盖全局a的局部变量)
  • @Quentin:你能用代码展示提升功能的外观吗?
  • @Brown_Dynamite — 看起来好像在问题中。它按此答案中描述的顺序运行。
  • 所以如果a没有被提升,调用函数b()会全局设置a = 10,那么alert(a)会输出10?如果我理解正确?
  • 理解提升的最好方法是像编译器一样说话,Grate
【解决方案2】:

这是因为此示例中的编译/解释顺序有些误导。 function a () {} 行在函数的任何其余部分执行之前被解释,所以在函数的最开始,a 的值是function a () {}。当您将其重新分配给10 时,您将在函数b() 的本地范围内重新分配a 的值,然后在您返回时将其丢弃,而将a = 1 的原始值留在全局范围内。

您可以通过在适当的位置放置alert()s 等来验证这一点,以查看a 在各个点的值。

【讨论】:

    【解决方案3】:

    (1) JavaScript 没有块语句作用域;相反,它将是块所在的代码的本地。

    (2) Javascript 在函数范围内声明变量,意思是在函数中声明的变量在该函数的任何地方都可用,甚至在它们被赋值之前.

    (3) 在函数体内,局部变量优先于同名的全局变量。如果你声明一个与全局变量同名的局部变量或函数参数,你有效隐藏全局变量.

    你的代码是一样的:(阅读评论)

    <script>
    var a = 1;          //global a = 1
    function b() {
        a = 10;         
        var a = 20;     //local a = 20
    }
    b();
    alert(a);           //global a  = 1
    </script>
    

    参考:
    (1)JavaScript Variable Scope:
    (2)A Dangerous Example of Javascript Hoisting
    (3)Variable scope

    所以在你的代码中:

    var a = 1;          //global a = 1  
    function b() {
        a = 10;         
        return;
        function a() {} //local 
    }
    b();
    alert(a);           //global a = 1  
    

    【讨论】:

    • 你在哪里写了“local a Undefined”——这实际上不是真的。函数声明在父范围的任何内容之前解析,因此在这种情况下,当您分配 a = 10 时,您已经用值 10 覆盖了函数 a() {}。请参阅 Quentin 的回答
    • @rochal 不,请阅读这篇文章Javascript hoisting can be especially nefarious in loops 还要检查 safari 浏览器上的代码...让我知道是的,它在大多数浏览器上是 a=10 ..实际上未定义的行为不是错误
    • 从昆汀的回答中阅读第 4 点。此时a 已经存在——它是一个函数,而不是未定义的。 Safari 与 Chrome 有什么不同?
    • @rochal variables declared in a function are available anywhere in that function, even before they are assigned a value 我也查了,给10 但是根据三个教程(我给了链接) 它应该是未定义的,并且 10 是由于未定义的结果。 Quentin 根据输出回答,但我认为某些浏览器可能不是 10..
    • 再一次,在您的示例代码中:a = 10; //local a Undefined不正确a = 10; //local a is function(){} 是正确的,因为一旦您检查内部函数 b() 的值,它就已经被本地函数 a(){} 覆盖,因此您对“local a Undefined”的评论无效。浏览器与它无关,它是一种语言功能。
    【解决方案4】:
    1. 函数声明function a(){}首先被提升,因此在本地范围内创建a
    2. 如果您有两个同名变量(一个在全局另一个在本地),则局部变量总是优先于全局变量。
    3. 当您设置a=10 时,您设置的是局部变量a,而不是全局变量。

      因此,全局变量的值保持不变,你会得到,alerted 1

    【讨论】:

      【解决方案5】:

      当我读到你写的JavaScript Scoping and Hoisting 的同一篇文章时,我也很困惑,因为作者从未展示过编译器中的两个开放示例代码的解释。

      这是您提供的示例,以及页面上的第二个示例:

      var a = 1;
      function b() {
          function a() {} // declares 'a' as a function, which is always local
          a = 10;
          return;
      }
      b();
      alert(a);
      

      这是页面上的第一个示例:

      var foo = 1;
      function bar() {
          var foo; // a new local 'foo' variable
          if (!foo) {
              foo = 10;
          }
          alert(foo);
      }
      bar();
      

      希望这可以帮助

      【讨论】:

      猜你喜欢
      • 2013-02-25
      • 2017-01-08
      • 2016-04-05
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2018-06-10
      相关资源
      最近更新 更多