JavaScript“吊装”

我偶然发现 JavaScript 的“提升”功能,但我不知道这段代码到底是如何工作的:

var a = 1;


function b() {
a = 10;
return;


function a() {}
}


b();
alert(a);

我知道像(function a() {})这样的函数声明将被悬挂到函数 b作用域的顶部,但是它不应该覆盖 a的值(因为函数声明覆盖了变量声明,但是没有覆盖变量初始化) ,所以我希望警报的值应该是10而不是1!

11283 次浏览
  1. The global a is set to 1
  2. b() is called
  3. function a() {} is hoisted and creates a local variable a that masks the global a
  4. The local a is set to 10 (overwriting the function a)
  5. The global a (still 1) is alerted

It's because the order of compilation/interpretation in this example is somewhat misleading. The function a () {} line is interpreted before any of the rest of the function is executed, so at the very beginning of the function, a has the value of function a () {}. When you reassign it to 10, you are reassigning the value of a in the local scope of function b(), which is then discarded once you return, leaving the original value of a = 1 in the global scope.

You can verify this by placing alert()s or the like in the appropriate places to see what the value of a is at various points.

(1) JavaScript does not have block statement scope; rather, it will be local to the code that the block resides within.

(2) Javascript's declaration of variables in a function scope, meaning that variables declared in a function are available anywhere in that function, even before they are assigned a value.

(3) Within the body of a function, a local variable takes precedence over a global variable with the same name. If you declare a local variable or function parameter with the same name as a global variable, you effectively hide the global variable.

you code is same as: (read comment)

<script>
var a = 1;          //global a = 1
function b() {
a = 10;
var a = 20;     //local a = 20
}
b();
alert(a);           //global a  = 1
</script>

reference:
(1) JavaScript Variable Scope:
(2) A Dangerous Example of Javascript Hoisting
(3) Variable scope

So in your code:

var a = 1;          //global a = 1
function b() {
a = 10;
return;
function a() {} //local
}
b();
alert(a);           //global a = 1

When I read the same article you did JavaScript Scoping and Hoisting, I was confused as well because the author never showed what the two opening example codes are interpreted as in the compiler.

Here is example you provided, and the second on the page:

var a = 1;
function b() {
function a() {} // declares 'a' as a function, which is always local
a = 10;
return;
}
b();
alert(a);

and here is the first example on the page:

var foo = 1;
function bar() {
var foo; // a new local 'foo' variable
if (!foo) {
foo = 10;
}
alert(foo);
}
bar();

Hope this helps

  1. function declaration function a(){} is hoisted first, hence in local scope a is created.
  2. If you have two variable with same name (one in global another in local), local variable always get precedence over global variable.
  3. When you set a=10, you are setting the local variable a , not the global one.

Hence, the value of global variable remain same and you get, alerted 1