吊装范围可变

Chr*_*ine 3 javascript variables scope hoisting

有人会帮助解释为什么下面的两个代码片段打印出不同的结果吗?

区别在于条件语句中。在第一个中,有一个名为'Jack'的局部变量分配给name,条件是真实的(意味着!name的值为true)。在第二个中,为全局变量名称分配了相同的名称“ Jack”,但条件是虚假的(!name为false)。我的问题是,如果所有这些都不是一样的,为什么会第一个条件是真实的,第二个是假的,如果有什么改变是内部条件体?

我唯一的解释是,条件的主体首先由JS解释器读取,这是它确定name全局/局部,是否需要提升变量声明以及最后记录不同名称值的方式。

甚至在开始解释其主体之前,是否不应该首先评估条件布尔值?然后,在两种情况下,变量“名称”都将被评估为“未定义” ...任何帮助将不胜感激!

关于提升/作用域上下文,确实有一些很好的资源,但是我找不到一个专门回答此问题的资源。

http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/

var name = "Paul"; 
function users () {
    if (!name) {
        var name = "Jack";  //<== difference is here, *inside* conditional body
    }
    console.log(name);
}
users(); //outputs "Jack"
Run Code Online (Sandbox Code Playgroud)

var name = "Paul"; 
function users () {
    if (!name) {
       name = "Jack";  //<== difference is here, *inside* conditional body
    }
    console.log(name);
}
users();  //outputs "Paul"
Run Code Online (Sandbox Code Playgroud)

Tra*_*s J 5

变量声明位于执行上下文的顶部,在这种情况下为函数用户。重写这些内容以从悬挂的角度显示外观,通常可以消除任何混乱

var name = "Paul"; 
function users () {
    var name;//<- hoisted variable declaration
    if (!name) {
        name = "Jack";
    }
    console.log(name);
}
users(); //outputs "Jack"
Run Code Online (Sandbox Code Playgroud)

var name = "Paul"; 
function users () {
    if (!name) {//no hoisted variable declaration, uses global
       name = "Jack";
    }
    console.log(name);
}
users();  //outputs "Paul"
Run Code Online (Sandbox Code Playgroud)

执行上下文包含几个关键组件,其中最相关的是词汇环境和变量环境。如果您对此感兴趣,我将更深入地介绍两者之间的区别(以及一些简要的历史):https : //stackoverflow.com/a/32573386/1026459