Javascript中的块作用域、函数作用域和本地作用域

Block scope, function scope and local scope in Javascript

本文关键字:作用域 函数 Javascript      更新时间:2023-09-26
  1. 块作用域有时是否与函数作用域相同?我知道函数作用域适用于函数内部的所有内容,但不知道block作用域到底是什么
  2. 对于Javascript,是否当前建议将来维护时使用let/const而不是var?(这来自Airbnb风格指南(
  1. javascript 5不使用阻塞作用域,而是使用链式作用域。主要区别在于,除非将变量设置为全局变量,否则无法访问作用域之外的变量。当您用let声明一个变量时,ES6将具有阻塞的作用域
  2. 目前建议使用var,因为ES 6没有得到完全支持

我不确定你的问题是否真的得到了回答:

块作用域有时与函数作用域相同吗?我知道函数范围适用于函数内部的所有内容,但不知道一个区块范围就是。

,块作用域有时与函数作用域相同。块范围是一组大括号{ a block scope here }内的所有内容。因此,在函数代码的顶部,块作用域将与函数作用域相同:

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/constvar的未来维护?(这来自Airbnb风格指南(

letconst是最新ES6规范的一部分,仅在最新的Javascript引擎中实现,有时在最新引擎中仅使用特殊标志启用。它们出现在所有较新的JS引擎/浏览器中,但尚未广泛部署。因此,如果您正在为在广泛的互联网上正常使用浏览器编写Javascript,那么您还不能可靠地使用letconst

在某些情况下,您现在可以安全地使用letconst进行编程:

  1. 如果您只针对特定的Javascript引擎,并且您知道它支持这些功能(例如特定版本的nodejs或仅适用于特定浏览器特定版本的插件(。

  2. 如果你使用的是一个可以将你的代码转换为在所有浏览器中运行的代码的转发器。当使用转译器时,你可以使用最新的功能编写代码,转译器会"静音",这样你的代码就可以通过模拟新功能在旧的浏览器中工作。

如果您正在为一个您知道支持letconst的环境进行编程,那么建议酌情使用它们。如果在函数的顶部声明一个变量,那么letvar将执行相同的操作。

如果在函数的较小范围内声明变量,则let将包含在较小范围内,但var将被提升到函数的顶部,并且将具有函数范围,无论它在哪里声明。


您链接到的AirBnb风格指南是专门为ES6环境编写的(请注意,他们的风格指南的ES5版本有一个单独的链接(。因此,这意味着他们假设了一个支持ES6的环境。这要么是因为他们的目标是一个服务器端JS引擎,他们知道该引擎支持ES6,要么因为他们使用的是一个将ES6代码转换为在ES5引擎上运行的代码的转发器。


关于转发器的说明在使用转译器并将块范围内的所有变量声明切换到let之前,有必要了解转译器生成的代码类型以及它生成的额外代码是否会对应用程序的性能产生任何影响。例如,let的块范围是通过创建一个内联IIFE来模拟的,这可能会导致每个包含let语句的块都有额外的运行时开销。我并不是说这一定是一件不好的事情,会阻止你使用转译器,但在决定是否使用转译机时,我建议你彻底熟悉各种ES6功能的转译代码,这样你就知道它是适合你的任何工作还是只适合某些工作。

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

块范围是中的所有内容,例如:

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这样的transpiler,或者暂时继续使用var