嵌套块作用域中的函数声明

4
与此参考资料相同,函数声明语句和变量声明不具有块级作用域。因此,我想知道下面的代码为什么会以这种方式执行。

    //javascript es6
    {
        function bar() {
            console.log("1");
        }
    }
    function bar() {
        console.log("2");
    }

    bar(); //prints "1" not "2"
    this.bar() //also prints "1" not "2"

我知道的是上面的代码应该考虑全局作用域中的两个函数,但似乎函数声明受块级作用域的影响。

2
this.bar() 在 FF 中触发错误(包括 window.bar())(“_TypeError:this.bar不是一个函数_”)。 - Teemu
它在我使用的谷歌浏览器最新版本上运行良好。 - Kirollos Nasr
2个回答

4

基本上,函数声明会在代码执行之前运行。让我尝试更清楚地表述一下。

首先让我们将函数重命名为这个,这样我可以更好地解释它是如何工作的:

    {
        function bar() {
            console.log("1");
        }
    }
    function foo() {
        console.log("2");
    }

你的编译器会扫描你的js文件,并看到有一个函数声明,即foo函数(忽略括号内的函数)。然后像通常一样运行js文件,进入括号并看到另一个函数声明(bar()函数),该函数在foo()函数之后声明。因此,基本上你会得到以下结果:

bar() // returns "2"

{
    function bar() {
        console.log("1")
    }
}
bar() // returns "1"

function bar() {
    console.log("2")
}

bar() // returns "1"

我希望您能理解。

如需更多信息,请尝试查找函数表达式与函数声明的区别,并了解JavaScript编译器的工作原理,这将使您更好地理解变量提升的工作原理。


很好,但为什么在声明变量时使用var就不能这样工作。 - Kirollos Nasr
var_、_letconst 变量的提升方式是不同的。我建议阅读这篇文章(https://scotch.io/tutorials/understanding-hoisting-in-javascript)。 - Dokt
1
没问题。希望能有所帮助。 - Dokt
回答不错,但请在您的第二个代码示例中将2更改为1,就像原始问题中一样 :) 我浪费了2分钟才注意到它们混淆了。 - Proo1931

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接