挂起没有'var'声明的JS变量

a3o*_*orm 3 javascript scope hoisting

我试图了解JavaScript中的提升和范围,并试图找出这段代码中究竟发生了什么.console.log(outside)console.log(local)这两个日志不确定,正如我预料的那样,outside是宣告但尚未初始化,并声明local被提升到函数的顶部.但为什么typeof global等于'undefined'.不是var在函数内部省略与在全局范围内声明变量相同 - 在这种情况下不会被提升?

var outside;
(function() {
    i = 2;
    if (i == 1) {
        var local = 'local';
        global = 'global';
    }
    // Demonstrates that local variables are hoisted but global variables are not.
    console.log(outside); // undefined
    console.log(local); // undefined
    console.log(global); // Uncaught ReferenceError: global is not defined. (i.e. typeof global === 'undefined')
})();
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/ffjiang/sYvbL/

jfr*_*d00 6

首先,仅var提升定义的变量.

分配给先前未声明的变量会在分配发生时创建该名称的全局.

尝试读取先前未声明的变量会导致引用错误,除非您使用包含对象作为前缀,例如window.global在这种情况下它将返回与尚不存在的对象的任何其他属性相同的内容undefined.

您的代码基本上等同于此(添加了一个console.log()语句):

var outside;      // declared as a global
(function() {
    var local;    // the declaration of this variable is hoisted to here
    i = 2;
    if (i == 1) {
        local = 'local';
        global = 'global';   // creates a global variable only when this line is executed
    }
    console.log(outside);        // undefined
    console.log(local);          // undefined
    console.log(window.global);  // undefined        
    console.log(global);         // Uncaught ReferenceError, no symbol of this name is found
})();
Run Code Online (Sandbox Code Playgroud)

这意味着在您尝试使用它们时定义了两者outside,local因此没有引用错误.两者都没有初始化,所以他们的价值是undefined. global当您尝试引用它时未定义,因为您没有执行它的赋值,因此它不存在.使用时没有提升全局变量的创建var.只有在实际执行分配给它们的代码时才会创建这些变量.