JavaScript'吊装'

mor*_*oce 83 javascript hoisting

我遇到了JavaScript'hoisting',我没有弄清楚这段代码是如何起作用的:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}

b();
alert(a);
Run Code Online (Sandbox Code Playgroud)

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

Que*_*tin 111

  1. 全局a设定为1
  2. b() 叫做
  3. function a() {}被悬挂并创建一个掩盖全局变量的局部变量aa
  4. 本地a设置为10(覆盖函数a)
  5. 全局a(静止1)被警告

  • 谢谢@Quentin我错过了第3个事实(函数a(){}创建了一个掩盖全局的局部变量a) (2认同)

小智 6

这是因为这个例子中的编译/解释顺序有些误导.function a () {}在执行任何其余函数之前解释该行,因此在函数的最开始,a其值为function a () {}.当您重新分配它时10,您将重新分配a函数的本地作用域中的值b(),然后在返回后将其丢弃,并将原始值保留a = 1在全局作用域中.

您可以通过alert()在适当的位置放置s等来验证这一点,以查看a各个点的值.


Gri*_*han 5

(1)JavaScript没有块语句范围; 相反,它将是块所在代码的本地代码.

(2)Javascript在函数作用域中声明变量,这意味着函数中声明的变量在该函数中的任何位置都可用,甚至在它们被赋值之前.

(3)在函数体内,局部变量优先于具有相同名称的全局变量.如果声明一个与全局变量同名的局部变量或函数参数,则可以有效地隐藏全局变量.

你的代码与:( 读评论)

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

参考:
(1)JavaScript变量范围:
(2) Javascript吊装的危险示例
(3)变量范围

所以在你的代码中:

var a = 1;          //global a = 1  
function b() {
    a = 10;         
    return;
    function a() {} //local 
}
b();
alert(a);           //global a = 1  
Run Code Online (Sandbox Code Playgroud)