我试图了解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')
})();
答案 0 :(得分:7)
首先,仅提升使用var
定义的变量。
分配给先前未声明的变量会在分配发生时创建该名称的全局。
尝试读取先前未声明的变量会导致引用错误,除非您使用window.global
之类的包含对象作为前缀,在这种情况下,它将返回与不包含对象的任何其他属性相同的内容#39; t尚未存在,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
})();
这意味着在您尝试使用它们时定义了outside
和local
,因此没有引用错误。两者都没有初始化,因此它们的值为undefined
。当您尝试引用它时未定义global
,因为您没有执行它的赋值,因此它不存在。使用var
创建全局变量没有任何提升。只有当实际执行分配给它们的代码时,才会创建这些变量。
答案 1 :(得分:1)
因为你向外部分配了一个值(未定义)
var outside = 5; // <=outside is 5
(function() {
i = 2;
if (i == 2) { // Condition is not satisfied. So variables are not declared. Replace to i==2;
var local = 'local';
global = 'global';
}
// Demonstrates that local variables are hoisted but global variables are not.
console.log(outside); // 5
console.log(local); // local
console.log(global); // global
return true
})();
答案 2 :(得分:1)
不会挂起global
,因为它未在函数体内使用var
声明1>};只有local
被悬挂。
global = 'global';
如果该语句运行,它将隐式创建一个全局声明,如果它尚不存在。
但它不是(运行),所以当你试图引用它时,它会合理地引发一个ReferenceError。
答案 3 :(得分:0)
如果使用var
声明变量,则声明将向上传播到最近的范围(在您的情况下为函数定义)。但是,没有var
的变量都被隐式指定为window
对象的属性。
因此,在您的示例中,global = 'global'
与window.global = 'global'
基本相同。由于代码永远不会被执行,window
不会获得此属性,当您在console.log
中访问它时,它没有被定义。