【问题标题】:JavaScript var keyword: redefining a variable's value inside a closureJavaScript var 关键字:在闭包中重新定义变量的值
【发布时间】:2016-06-05 19:12:43
【问题描述】:

我在这里缺少什么?这符合预期:

var x = 1;
(function(){
   // x === 1
})();

但是,

var x = 1;
(function(){
   var x = x;
   // x is undefined
})();

我认为 x 应该是 1。似乎var x = x 在分配 x 之前核对了它的值。这是一个错误吗?这似乎不太直观。

这种行为是否改变了?我记得以前做过like this 的事情。

供参考:

var x = 1;
(function(){
    var y = x;
    // y === 1
})();

还有:

var x = 1;
(function(){
    x = x;
    // x === 1
})();

【问题讨论】:

  • 通常在声明 var 的任何地方,它都好像是在函数的最开头(在任何赋值之前)声明的。

标签: javascript var


【解决方案1】:
var x = 1;
(function(){
   var x = x;
})();

variable hoisting 之后变为:

var x = 1;
(function(){
   var x;
   x = x;
})();

【讨论】:

  • this 怎么样?如果您的解释是正确的,则链接的小提琴应该可以工作,但不能。
  • @nicael 两个 var 声明都被提升到了赋值之上
  • 好吧,你应该也解释一下。
  • 那为什么this 会起作用?我以前见过这样做,并且有几个关于相同var x = x || {} 模式的问题。他们是否在某个时候改变了这种行为?
  • @MikeLewis 因为这是文件的开头,而不是函数。如果在浏览器中包含多个 javascript 文件,则它们将一个接一个地执行,并且如果变量之前已在本地声明,则新的 local 声明将被忽略,但分配将被保留。
【解决方案2】:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/var

因为变量声明(以及一般的声明)是在任何代码执行之前处理的,所以在代码的任何地方声明一个变量就相当于在顶部声明它。这也意味着一个变量在它被声明之前可以被使用。这种行为称为“提升”,因为变量声明似乎被移到函数或全局代码的顶部。

这就是为什么有时在插件中你会看到类似这样的代码

var i,j,abc, d;

//code

在您的示例中,代码转换如下:

function() {
    var x;
    x = x;
}

函数参数的例子不同,你只需改变函数参数本身,var 声明就会被忽略。

如果使用let 声明了一个作用域变量,它只会向上移动到该作用域的开头而不是函数的开头,所以这段代码有效:

var x = 1;
(function(){
   var y = x;
   {
        let x = y;
        console.log(x);
   }
})();

正如所指出的,这是一个新功能,所以not supported everywhere

最后,这里:

var x = 1;
(function(){
    x = x;
    // x === 1
})();

你没有在本地声明x,所以如果你编辑它,它也会在全局范围内编辑它。

【讨论】:

    【解决方案3】:

    在 JavaScript 中,所有变量声明在全局范围内或声明的整个函数范围内。考虑示例:

    var x = 1;
    
    function f()
    {
        console.log(x);
        if (true) {
            var x;
        }
    }
    
    f();
    

    这是一种奇怪的编程语言设计,但由于这条规则,这段代码也会打印“未定义”。

    【讨论】:

      【解决方案4】:

      每次您键入 var 时,您都会重新分配一个新变量。当您只是在函数内引用 x 时,它会查找上面的赋值语句。

      function f(){
          var x = x;  //this tries to reassign var x to undefined.
      }
      

      【讨论】:

        【解决方案5】:

        您在这里所做的是将 x 设置为全局变量,然后将其设置为引用自身,覆盖 1,使 x => x 未定义。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-30
          • 2012-03-07
          • 2013-01-09
          • 2020-09-20
          • 2021-08-02
          • 1970-01-01
          相关资源
          最近更新 更多