Variable hoisting(变量提升)
《摘自Object Oriented JavaScript,3rd Edition》
Here’s an interesting example that shows an important aspect of local versus global scoping:
var a = 123;
function f() {
alert(a);
var a = 1;
alert(a);
}
f();
You might expect that the first alert() function will display 123 (the value of the global variable a ) and the second will display 1 (the local variable a ). But, this is not the case. The first alert will show undefined . This is because, inside the function, the local scope is more important than the global scope. So, a local variable overwrites any global variable with the same name. At the time of the first alert() , the a variable was not yet defined (hence the undefined value), but it still existed in the local space due to the special behavior called hoisting. When your JavaScript program execution enters a new function, all the variables declared anywhere in the function are moved, elevated, or hoisted to the top of the function. This is an important concept to keep in mind. Further, only the declaration is hoisted, meaning only the presence of the variable is moved to the top. Any assignments stay where they are. In the preceding example, the declaration of the local variable a was hoisted to the top. Only the declaration was hoisted, but not the assignment to 1 . It’s as if the function was written in the following way:
你可能期望第一个alert()函数会显示123
(就是全局变量a的值)和第二个将会显示1
(局部变量a)。但是这里不是。第一个显示undefinded
。这是因为在函数的内部,局部变量比全局变量更为重要。因此,局部变量a
会重写任何带有相同变量名称的全局变量。在第一个alert()
的时候,这个局部变量还没有被定义(因此是undefined
),但是由于一种特别的行为叫做hoisting
,这个局部变量a
仍会存在于局部空间。当你的程序进入到一个新的函数,所有在这个函数中定义申明的变量会被移除,evelated(提升),或者被提升到这个函数的top,这是一个重要的理念要保存到脑海。更进一步,这个只是变量的申明会被提升,意味着仅仅只有当前的变量都会移至到顶部。其他的不变。在之前的例子中,这个局部变量的申明被提升到了顶部。仅仅只有申明会被提升,但不会给变量赋值为1
。就像下面的函数描述的一样:
var a = 123;
function f() {
var a; // same as: var a = undefined;
alert(a); // undefined
a = 1;
alert(a); // 1
}
You can also adopt the single var pattern mentioned previously in the best practice section. In this
case, you’ll be doing a sort of manual variable hoisting to prevent confusion with the JavaScript
hoisting behavior.
你也可以采用单一变量像之前在最佳实践章节提到的一样。在这个例子里,你可能会手动处理变量的提升去阻止JavaScript提升行为带来的困惑