考虑到函数提升,为什么这三个 JavaScript 示例会产生不同的输出?

问题描述 投票:0回答:1

问题

我试图理解为什么以下三个 JavaScript 示例会产生不同的输出,尽管它们似乎都涉及函数提升。根据函数提升的工作原理,输出不应该是相同的吗?

示例1

var a = 0;
console.log("1 a:", a);
if(true){
    a = 1;
    function a() {}
    a = 5;
    console.log("2 a:", a);
}
console.log("3 a:", a);

输出为:

1 a: 0
2 a: 5
3 a: 1

已验证。

示例2

var a = 0;
console.log("1 a:", a);
if(true){
    a = 1;
    a = 5;
    console.log("2 a:", a);
    function a() {}
}
console.log("3 a:", a);

输出为:

1 a: 0
2 a: 5
3 a: 5

已验证。

示例3

var a = 0;
console.log("1 a:", a);
if(true){
    function a() {}
    a = 1;
    a = 5;
    console.log("2 a:", a);
}
console.log("3 a:", a);

输出为:

1 a: 0
2 a: 5
3 a: f a() {}

已验证。

我尝试过的事情

我已经阅读了 JavaScript 中的函数提升,但这些示例让我感到困惑。根据我对函数提升的理解,我不确定为什么它们不会产生相同的输出。

问题

  1. 这些示例在函数提升的上下文中有何不同?
  2. 为什么每个示例的输出不同?

任何见解将不胜感激!

javascript scope hoisting
1个回答
0
投票

这些示例因 JavaScript 引擎对变量和函数声明的处理而有所不同。让我们检查每个示例:

  • 示例1

    • 在块作用域中,
      a
      被声明为函数,然后重新分配给
      5
      。但是,由于 var 提升,函数声明仅提升到封闭函数或全局作用域,而不是块作用域。块外
      a
      的最终值为
      1
      ,而不是
      5
  • 示例2

    • 函数声明被提升到封闭函数或全局作用域,但不会在块作用域内执行,因为它是在重新分配之后出现的。
      a
      被分配
      5
      并保留该值在块之外。
  • 示例3

    • 这里,函数声明位于块作用域中的赋值之前。函数声明被提升,因此块内的变量
      a
      成为函数对象。块内对
      a
      的赋值不会影响块外的函数声明,导致函数被打印为块外
      a
      的值。

关键要点是,对于

var
声明、
let
/
const
声明和函数声明,提升的行为有所不同,并且可能会受到代码中声明和赋值的特定定位的影响。值得注意的是,块作用域中函数声明的行为依赖于实现,并且在不同的 JavaScript 引擎之间可能有所不同。

© www.soinside.com 2019 - 2024. All rights reserved.