【问题标题】:var Hoisting in JavaScript [duplicate]JavaScript中的var提升[重复]
【发布时间】:2021-01-24 18:49:55
【问题描述】:

考虑下面的 JavaScript 代码-

var DEFAULT_RATE=0.01;
var rate=0.04;
function getRate() {
  if(!rate) {
    var rate=DEFAULT_RATE;
  }
  return rate;
}
console.log(`Rate is`,getRate());

下面代码的输出是0.01 我从中得出的结论是,变量被提升(并声明为未定义)到与它们使用位置有关的范围的顶部。在 let 和 const 的情况下,它们会进入 TDZ,但这完全是另一回事。

但我也了解到 var 具有全局范围。然后 var show 不允许变量重新声明。

全局作用域不就是包含整个代码的作用域吗?我理解错了吗?

【问题讨论】:

  • 请注意,var 本质上是遗留语法,您希望将letconst 用于您编写的任何新代码,因为它们是块范围的并且没有var 遭受的古怪的范围界定陷阱。话虽如此,你能解释一下你的外卖是基于什么吗? var 是函数范围的(因此变量 declaration 在解析时被提升到函数的顶部,同时将 initialization 留在它找到它的位置。如果使它隐藏一个现有的变量,太糟糕了)除非在全局范围内声明,在这种情况下,同样的事情会发生,但是是全局的。
  • 这能回答你的问题吗? Why a variable defined global is undefined?
  • 这是一个由 if 块内的var rate=DEFAULT_RATE 引起的丑陋的吊装问题,与function getRate() { var rate; if (!rate) {rate=DEFAULT_RATE;} return rate;} 相同。 getRate 将始终返回 DEFAULT_RATE.,因为 getRate 中的 if 语句将始终为真。

标签: javascript


【解决方案1】:

当使用var 声明变量时,变量可以采用函数或全局范围。如果在函数内使用var,则它具有函数作用域,如果在任何函数之外使用var,则变量具有全局作用域。

所以,你的陈述:

但我也了解到 var 具有全局范围。然后 var show 不允许 变量重新声明。

实际上,不是很准确,因为它取决于var 的使用位置,并且在比第一次声明更小的范围内重新声明(更正确地称为变量“隐藏”)是可能的。

使用var 声明时,声明被提升到作用域的顶部。

我已经写了another answer,详细描述和演示了这一点。

【讨论】:

    【解决方案2】:

    在 JavaScript 中,函数声明在 var 声明之前被提升,而赋值不会被提升。

    所以问题中的示例代码:

    var DEFAULT_RATE=0.01;
    var rate=0.04;
    function getRate() {
      if(!rate) {
        var rate=DEFAULT_RATE;
      }
      return rate;
    }
    

    有这个有效的排序:

    // hoisted function
    function getRate() {
      var rate = undefined; // <- hoisted local variable
      if(!rate) { // <- always true
        rate = DEFAULT_RATE; // <- always executed
      }
      return rate; // <- always returns DEFAULT_RATE (0.01)
    }
    
    // hoisted vars
    var DEFAULT_RATE;
    var rate;
    
    // not-hoisted assignments
    DEFAULT_RATE = 0.01;
    rate = 0.04;
    
    // not-hoisted function call
    console.log(`Rate is`,getRate());
    

    由于getRate() 包含var rate,函数作用域rate 被提升到getRate() 的开头,值为undefined

    因此,if(!rate) 的计算结果为 if(!undefined),这始终为真,getRate() 始终返回 DEFAULT_RATE (0.01)。

    【讨论】:

    • 不是if (!rate) 为真的原因。
    • @deceze 感谢您指出我没有注意到getRate 中的var rate 声明。答案已更正。
    猜你喜欢
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2013-02-25
    • 2014-05-17
    • 2017-01-08
    • 1970-01-01
    • 2021-02-21
    相关资源
    最近更新 更多