JavaScript中的块级作用域、函数作用域和局部作用域

9
  1. 块级作用域有时与函数作用域相同吗?我知道函数作用域适用于函数内的所有内容,但不明白什么是块级作用域。
  2. 对于Javascript,目前是否建议在未来维护中使用 let / const 而不是 var?(这是来自 Airbnb Style Guide 的建议)
3个回答

7
  1. JavaScript 5不使用块级作用域,而是使用链式作用域。主要区别是,除非将变量作为全局变量声明,否则无法访问作用域之外的变量。ES 6在使用let声明变量时会采用块级作用域。
  2. 目前建议使用var,因为ES 6尚未完全支持。

ES6的发布日期有预估吗?我想知道为什么Airbnb建议我们这么早就使用ES6的标准。 - chenghuayang
1
@ChenghuaYang:多年来,ES6规范的发布日期一直在估算中,我记得曾经有一段时间计划在2012或2013年完成。据我最后了解,是的,他们期望今年完成。但当然,你还需要等待供应商支持它,并等待人们升级他们的浏览器。至于Airbnb,也许他们正在进行转译,或者他们只是在推动一个议程。 - T.J. Crowder
1
@ChenghuaYang Airbnb团队已经开始使用ES6编写代码,但是他们使用转译器(例如TraceurBabel)将其转译为ES5,以便于在现代浏览器中使用。 - laruiss

5

我不确定您是否已经得到了答案:

块级作用域有时与函数作用域相同吗? 我知道函数作用域适用于函数内部的所有内容,但不明白什么是块级作用域。

是的,块级作用域有时与函数作用域相同。 块级作用域是一组大括号内的所有内容 { 这里是一个块级作用域 }。 因此,在函数代码的顶部,块级作用域将与函数作用域相同:

function test(x) {
   // this is both a block scope and a function scope
   let y = 5;
   if (x) {
       // this is a smaller block scope that is not the same as the function scope
       let z = 1;
   }
}

对于JavaScript,目前建议在未来维护时使用let / const而不是var吗?(这是来自Airbnb样式指南的)。 letconst是最新ES6规范的一部分,只在最新的Javascript引擎中实现,并且有时在最新的引擎中仅通过特殊标志启用。它们将出现在所有更新的JS引擎/浏览器中,但尚未广泛部署。因此,如果您正在编写面向广泛互联网的常规浏览器消费的JavaScript,则不能可靠地使用letconst
现在有一些情况可以安全地使用letconst
  1. 如果您只针对特定的Javascript引擎进行开发,并且您知道它支持这些功能(例如特定版本的nodejs或仅适用于特定浏览器版本的插件),那么可以使用这些功能。

  2. 如果您使用转译器将代码转换为在所有浏览器中运行的代码。使用转译器时,您可以使用最新的功能编写代码,转译器将“降级”代码以便在旧浏览器中使用模拟的新功能。

如果您正在为已知支持letconst的环境编程,则建议根据需要使用它们。如果您在函数顶部声明变量,则letvar将执行相同的操作。

如果您在函数内的较小范围内声明变量,则let将包含在较小的范围内,但var将被提升到函数的顶部,并具有函数作用域,无论在何处声明。


你提供的 AirBnb Style Guide 是针对 ES6 环境编写的(请注意,他们还有一个专门针对 ES5 版本的样式指南链接)。这意味着他们假定使用了 ES6 能力环境。这可能是因为他们正在针对支持 ES6 的服务器端 JS 引擎进行开发,或者他们正在使用转译器将 ES6 代码转换为可以在 ES5 引擎上运行的代码。
关于转译器的注意事项。在使用转译器并将所有变量声明切换为块级作用域中的let之前,值得了解转译器生成的代码类型以及它所生成的额外代码是否对应用程序的性能产生影响。例如,let的块级作用域是通过创建内联IIFE来模拟的,这可能会导致每个包含let语句的块都有额外的运行时开销。我并不是说这一定是一个应该阻止您使用转译器的坏事情,但在决定是否使用转译器时,建议您彻底熟悉各种ES6功能的转译代码看起来像什么,以便知道它是否是您拥有的任何工作的正确工具或仅适用于某些工作。

4

块作用域有时与函数作用域相同吗?我知道函数作用域适用于函数内部的所有内容,但不知道块作用域确切是什么。

块作用域是指在一个 内的所有内容,例如:

function foo() {
    // function scope
    if (condition) {
        // block scope
    }
}

直到第5版规范,JavaScript 没有块级作用域。下一个规范(ECMAScript 6,又称为“ES6”),几乎已经完成,通过 letconst 添加了块级作用域。

对于 JavaScript,是否建议在未来的维护中使用 let / const 替代 var?

这完全取决于您。 letconst 是您可以添加到工具箱的新工具。如果您不想这样做,它们并不一定需要替换 var。尽管如此,您常常会听到 "let 是新的 var"。
使用 let 声明变量具有块级作用域,而使用 var 声明变量则没有。
请注意,letconst在实际应用中的支持还不够完善。毫无疑问,将块级作用域添加到以前从未拥有过它的引擎中是相当困难的。您可以使用像Babel这样的转译器,或者现在继续使用var(链接)

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