【问题标题】:Variable hoisting examples [duplicate]变量提升示例 [重复]
【发布时间】:2016-01-14 16:59:26
【问题描述】:

您好,我有一段代码。当我删除相同代码的非相关部分时,我对值 x1 的变化感到困惑。我搜索了一下,我才知道它与吊装有关。但是对于我来说,即使有提升的概念,x1 的值仍然不清楚。有人可以帮我解释一下吗?

var x = 10;               
    
function main() {
  document.write("<br>x1 is " + x);
  x = 20;
  if (x > 0) {
    var x = 30;
    document.write("<br>x2 is " + x);
  }
  var x = 40;
  var f = function(x) { 
    document.write("<br>x3 is " + x); 
  }
  f(50);
}

main();

这段代码的输出是:

x1 未定义
x2 为 30
x3 是 50

如果我将此代码更改为:

        
var x = 10;

function main() {
  document.write("<br>x1 is " + x);  
}

main();

输出是:

x1 是 10

【问题讨论】:

    标签: javascript variables hoisting lexical-scope


    【解决方案1】:

    所有变量和函数声明都被“提升”或移动到其作用域的顶部。 xundefined 值是因为 var x 语句被移到了 main 的顶部,但赋值 = 30 没有。

    因此,您的代码将更像这样:

    var x = 10;                             // x is 10
    function main() {
        var x;                              // x declaration is "hoisted"
        document.write("<br>x1 is" + x);    // x1 is undefined
        x = 20;                             // x is 20
        if (x > 0) {
            x = 30;                         // x is 30
            document.write("<br>x2 is" + x);// x2 is 30
        }
        x = 40;                             // x is 40
        var f = function(x) {               // x is 50
            document.write("<br>x3 is" + x);// x3 is 50
        }
        f(50);
    }
    main();
    

    您可以在此处阅读有关吊装的更多信息:JavaScript Scoping and Hoisting

    【讨论】:

      【解决方案2】:

      所以这里发生的事情是一个常见的陷阱。

      最简单的说法是。当您在 main 函数内设置 var x = 30 时,实际上是在重新定义 var x = 10 在此函数内使用的范围。这与 Javascript 的执行方式和范围有关。

      通过在函数内部定义x,x 的作用域发生了变化。下面是我的意思的一个例子和你的代码的一个版本

      示例:

      var test = 'test';
      function run(){
          console.log(test);
          var test=1;
      }
      

      您的代码已更新:

      var x = 10; 
              function main() {
                  console.log("<br>x1 is " + x);
                  x = 20;
                  if (x > 0) {
                      x = 30;
                      console.log("<br>x2 is " + x);
                  }
                  x = 40;
                  var f = function(x) { console.log("<br>x3 is " + x); }
                  f(50);
              }
              main();

      好问题顺便说一句。

      由于这是 Javascript 执行方式的一个非常有趣的范围,请考虑以下代码及其输出以了解完整的想法

      var test = 'test';
      
      function run(){
        console.log(test);
        test=1;
        console.log(test);
        var test=2;
        console.log(test);
      }
      
      console.log(test);
      
      run();
      
      console.log(test);

      看看它的反应非常有趣。

      【讨论】:

      • 他们实际上在 var x = 30; 中重新定义了范围;他们将原始 x 签名为 20 就好了。
      • 不确定“杀死范围”是否正确。至少“删除它的范围”是错误的,如果至少是可怕的误导。只是有多个作用域,现在在不同的作用域中有两个变量具有同名
      • @Bergi - 你是对的,为未来的访问者编辑
      • @Jesse 在“您更新的代码”部分中,我可以看到您从 var x= 30 中删除了 var。我假设您这样做是为了使 x 范围全局化,这样它就不会在一个函数。这是有道理的,但是 x1 的输出仍然是未定义的,这意味着 var 或 no var 它对输出没有任何影响。
      猜你喜欢
      • 2014-12-31
      • 2019-05-07
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      相关资源
      最近更新 更多