JavaScript中未初始化变量的范围

Yam*_*cha 3 javascript

我无法理解为什么这段代码的行为如下:

for (var i = 1; i < 3; i++) {
    var j;
    if (!j) {
        j = 1;
    } else {
        alert("why are we here? j shouldn't be defined but it's " + j);
    }
}
Run Code Online (Sandbox Code Playgroud)

(jsFiddle)

如果我设置jnull和检查null,它的工作原理,我认为它应该的方式.

这不是Java,C#,C++等的工作方式,因而是混乱.

Ale*_*ara 10

这是因为JavaScript中的变量范围限定为函数(如果不在函数内,则为全局范围).A var不在循环内部,并且花括号不定义新的闭包.基本上,j循环体后持续存在的值,并且var不重新定义jundefined.这就是显式设置var j = null;具有预期效果的原因.

例1:

考虑到这一点的一个好方法是,只要你用var这样的方式声明一个变量.

function someFunc() {
    for(var i = 0; i < 3; i++){
        var j;
    }
}
Run Code Online (Sandbox Code Playgroud)

解释器像这样提升变量声明.

function someFunc() {
    var i;
    var j;
    for(i = 0; i < 3; i++){
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,由于var j声明被提升到函数的顶部,声明实际上在循环中什么都不做.

例2:

但是,如果您要使用null这样初始化变量.

function someFunc() {
    for(var i = 0; i < 3; i++){
        var j = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

它将被解释为这样.

function someFunc() {
    var i;
    var j;
    for(i = 0; i < 3; i++){
        j = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意每个循环j的设置方式null.

ES6 let关键字:

ES6中有一个关键字,它将在这样的循环中创建一个范围,它是let关键字.请记住,此时let关键字的浏览器支持很差.

for (var i = 1; i < 3; i++) {
    let j;
    if (!j) {
        j = 1;
    } else {
        alert("why are we here? j shouldn't be defined but it's "+ j);
    }
}
Run Code Online (Sandbox Code Playgroud)