JS 提升如何在函数中工作?

How JS hoisting works within functions?

谁能给我解释一下为什么 (1) returns 11 其中 (2) returns undefined。函数 blocks/declarations 对提升的影响是什么?

// (1)
var boo = 11
console.log(boo) // 11
var boo = 10

// (2)
var boo = 11
function foo() {
   console.log(boo)
   var boo = 10
}
foo() // undefined

不要在第一次需要覆盖 boo 后一直使用 var

编辑:它是未定义的,因为你声明了它两次

如果声明一次然后在函数中覆盖,只有 2 个可以正常工作

// (1)
var boo = 11
console.log(boo) // 11
 boo = 10

// (2)
var boo = 11
function foo() {
   console.log(boo)
   boo = 10
}
foo() // 11

如果你想在一个函数中过度声明并调用你至少需要在声明后对其进行控制台

    // (2)
    var boo = 11
    function foo() {
       boo = 10
       console.log(boo)
    }
    foo() // 10

JavaScript 函数内提升意味着变量的声明被移动到函数块的顶部。当你输入 foo() 时,即使你还没有到达它,也会立即重新声明 var boo (因为 JS 引擎知道这个声明存在于函数内部)。因此,它未定义的原因是因为它只是被声明,直到下一行才赋值。

实际上,如果您在适当的范围内声明变量并且不重新声明具有相同名称的变量,这不是您应该遇到的情况,但我理解您的好奇心。

您可以阅读更多相关信息 here

var 声明(与 let 相反)总是在其块的顶部完成,意思是:

var boo = 11
function foo() {
   console.log(boo)
   var boo = 10
}
foo()

等于

var boo = 11
function foo() {
   var boo // undefined
   console.log(boo)
   boo = 10 // 10
}
foo()

每个执行上下文都会发生提升。在提升期间,变量或函数声明不会移动到顶部,它们只是被写入内存。

当您 运行 一个 javascript 文件时,将创建第一个全局执行上下文。全局执行上下文赋予全局对象、“this”关键字并提升 var 声明和函数声明。

在你问题的第一部分:

var boo = 11
console.log(boo) // 11
var boo = 10

boo是这样吊起来的:

var boo=undefined. 

因为变量被部分提升了。 var boo=10 不会覆盖 var boo=undefined。这是吊装后的样子:

var boo=undefined
    boo = 11
    console.log(boo) // it is clear why 11
    var boo = 10

在你问题的第二部分:

var boo = 11
function foo() {
   console.log(boo)
   var boo = 10
}
foo() 

全局上下文中的 var boo 已部分提升。

var boo=undefined

但这与我们无关。因为当我们创建一个新函数并调用它时,会创建一个新的执行上下文,并且在此执行上下文中会发生另一个提升,如下所示:

function foo() {
   var boo=undefined  
   // "boo" is partially hoisted inside  
   // "boo" is written into the variable environment of the execution context
   // "foo()" will always look into the its variable environment first
   console.log(boo)
   boo = 10
}

我们不止一次定义了一个变量,但在不同的范围内。我们在父范围内有 var boo =11,在本地范围内有 var boo=10。这是一个变量阴影的例子。 foo() 将首先使用局部变量,因此局部变量会覆盖父变量的值。