相关文章推荐
本文用于帮助理解旧脚本

本文所讲的内容对于帮助理解旧脚本很有用。

但这不是我们编写新代码的方式。

在本教程最开始那部分的 变量 这章中,我们提到了变量声明的三种方式:

  • const
  • var 声明与 let 相似。大部分情况下,我们可以用 let 代替 var 或者 var 代替 let ,都能达到预期的效果:

    但实际上 var 却是一头非常不同的,源自远古时代的怪兽。在现代脚本中一般不再使用它,但它仍然潜伏在旧脚本中。

    如果你不打算接触这样的脚本,你甚至可以跳过本章或推迟阅读本章。

    另一方面,了解将旧脚本从 var 迁移到 let 时的区别,以避免奇怪的错误,是很重要的。

    “var” 没有块级作用域

    var 声明的变量,不是函数作用域就是全局作用域。它们在代码块外也是可见的(译注:也就是说, var 声明的变量只有函数作用域和全局作用域,没有块级作用域)。

    举个例子:

    “var” 声明的变量,可以在其声明语句前被使用

    当函数开始的时候,就会处理 var 声明(脚本启动对应全局变量)。

    换言之, var 声明的变量会在函数开头被定义,与它在代码中定义的位置无关(这里不考虑定义在嵌套函数中的情况)。

    那么看一下这段代码:

    人们将这种行为称为“提升”(英文为 “hoisting” 或 “raising”),因为所有的 var 都被“提升”到了函数的顶部。

    所以,在上面的例子中, if (false) 分支永远都不会执行,但没关系,它里面的 var 在函数刚开始时就被处理了,所以在执行 (*) 那行代码时,变量是存在的。

    声明会被提升,但是赋值不会。

    我们最好用例子来说明:

    因为所有的 var 声明都是在函数开头处理的,我们可以在任何地方引用它们。但是在它们被赋值之前都是 undefined。

    上面两个例子中, alert 运行都不会报错,因为变量 phrase 是存在的。但是它还没有被赋值,所以显示 undefiend

    IIFE

    在之前,JavaScript 中只有 var 这一种声明变量的方式,并且这种方式声明的变量没有块级作用域,程序员们就发明了一种模仿块级作用域的方法。这种方法被称为“立即调用函数表达式”(immediately-invoked function expressions,IIFE)。

    如今,我们不应该再使用 IIFE 了,但是你可以在旧脚本中找到它们。

    IIFE 看起来像这样:

    // 尝试声明并立即调用一个函数
    function() { // <-- SyntaxError: Function statements require a function name
      var message = "Hello";
      alert(message); // Hello
          

    即使我们说:“好吧,那我们加一个名称吧”,但它仍然不工作,因为 JavaScript 不允许立即调用函数声明:

     
    推荐文章