为什么块作用域最初没有在 JavaScript 中实现?

我曾经阅读过,并且通过我自己的经验发现,JavaScript 没有块作用域。假设这种语言被设计成这样是有原因的,你能向我解释一下是什么原因吗?

我已经在 Google 和这里看过了,但是我发现的文章只是重申了 JS 有一个函数作用域而不是块作用域,没有解释原因。我很好奇为什么会这样。

14082 次浏览

原因有很多,但我们想到的一些原因是为了帮助解析/调试使用对象文本(有时看起来像块)的代码,以及简化本地变量的垃圾收集。

我希望所承诺的支持(例如,这里讨论的 http://esdiscuss.org/notes/2012-07-25)是真实的,因为使用像 i这样只局部于单个循环的变量是非常方便的。

将我的评论转换为答案

创造者的选择: 我在推特上发布了布兰登的消息,得到了 以下回答:

@ mplugjan 10天没有留出时间进行区块范围。同时,90年代中期的许多“脚本语言”的作用范围很小,后来才发展起来。


也就是说,这里有一些相关的观点:

重要提示: ECMAScript2015(第6版)之前的 JavaScript 没有块作用域。在块中引入的变量的作用域是包含函数或脚本,并且设置它们的效果超出了块本身。换句话说,块语句不引入作用域。尽管“独立”块是有效的语法,但是您不希望在 JavaScript 中使用独立块,因为如果您认为它们在 C 或 Java 中做类似的事情,那么它们不会做您认为它们会做的事情。

我们可以通过创建新函数并立即调用它们来人为地引入作用域

letconst声明的变量被悬挂,但它们是 没有初始化为 undefined的方式与 var相同。因此,在赋值之前引用 letconst声明的变量会引发 ReferenceError。

在同一块作用域中重新声明同一变量会引发 SyntaxError。

由于以下原因,没有实施块范围:

  1. 这使得语言更容易实现。JavaScript 最初是作为一种编写交互式 Web 应用程序的语言而设计的。因此,它需要规模小且易于实现。
  2. 块作用域为 JavaScript 等动态语言带来了性能上的冲击。这是因为当您尝试访问某个不在当前作用域中的变量时,JavaScript 首先检查当前作用域,然后检查父作用域,依此类推,直到找到变量或者到达结束。因此,引入块作用域将使循环和嵌套循环中的变量访问非常缓慢。
  3. 块作用域的缺乏使得编写程序更加容易。例如,假设只有在某个条件为真时才创建变量。在 JavaScript 中,您所需要做的就是在 if语句中声明和定义变量。在像 C 这样的语言中,您必须在 if语句之外声明变量,并在 if语句中定义它。
  4. 没有块作用域允许挂起声明。这在函数声明的情况下特别有用。例如,请看这个小提琴: http://jsfiddle.net/L6SgM/(但是请注意,这个示例在 Firefox 中不能工作)。
  5. 由于 JavaScript 支持第一类函数表达式,我们不需要块作用域,可以使用 立即调用的函数表达式模拟它们。

新的答案是2015年。 ES6确实有块范围的变量定义与 letconst关键字。