JavaScript var关键字:在闭包内重新定义变量的值

时间:2016-06-05 19:12:43

标签: javascript var

我在这里缺少什么?这表现得如预期:

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

5 个答案:

答案 0 :(得分:4)

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

variable hoisting成为后:

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

答案 1 :(得分: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,因此如果您对其进行编辑,它也会在全局范围内对其进行编辑。

答案 2 :(得分:1)

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

var x = 1;

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

f();

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

答案 3 :(得分:-1)

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

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

答案 4 :(得分:-2)

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