为什么块作用域最初不是在JavaScript中实现的?


71

我已经阅读并通过我自己的经验发现,JavaScript没有块作用域。假设这种语言是出于某种原因而设计的,您能向我解释那是什么原因吗?

我已经在Google和此处四处查看,但是我发现的帖子只是重申JS具有函数作用域而不是块作用域,而没有解释原因。我很好奇为什么会这样。


4
我想JavaScript中的函数式编程风格不鼓励这样做,而JS是一个匆忙的概念,但letES6中即将出现,因此在不久的将来我们将具有块作用域。Firefox已经支持let
Elclanrs 2013年

该语言的创建者回答了@Aadit的问题和解释,我本人似乎也涵盖了其他所有问题,因此我认为它不再只是意见。
mplungjan

Answers:


114

将我的评论转换为答案

创建者的选择:我在Brendan上发布了一条推文,得到以下答案

@mplungjan 10天没有为块范围保留时间。同样,在90年代中期的许多“脚本语言”的作用域也很少,后来又增加了。


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

重要提示:ECMAScript2015(第6版)之前的JavaScript没有阻止范围。块中引入的变量的作用域为包含的函数或脚本,并且设置变量的效果将持续到块本身之外。换句话说,block语句不会引入作用域。尽管“独立”块是有效的语法,但是您不希望在JavaScript中使用独立块,因为如果您认为独立块在C或Java中的作用类似于此类块,则它们不会像您想的那样工作。

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

letconst声明的变量高挂,但他们都没有初始化undefined以同样的方式var是。因此,在赋值之前声明一个letconst声明的变量会引发ReferenceError。

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


我不太了解“,let并且已const声明的变量已被吊起,但undefined直到我查看此代码示例之前,它们都未初始化为”。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference / ...您是否正在使用该语句谈论时间盲区?
christo8989

15

截至2015年的新答案。ES6确实具有使用letconst关键字的变量定义的块范围。


2
不幸的是,有些用户可能仍然生活在2010年,因此依靠全新的语言功能并不是最佳实践。
riv

1
@riv-Java不仅用于必须使用最低公分母进行编码的浏览器。它可以在诸如node.js之类的环境中使用,您可以在其中控制整个执行环境并立即使用let。或者,您可以使用一种可让您在ES6中编写代码的编译器,然后该编译器将其转换为与ES5兼容的代码,从而使其可以在较旧的浏览器中运行。
jfriend00 2015年

没有一个新的答案,原因有的js块范围与try/catchES3

@Trung-您能提供一个可以解释这一点的参考吗?我看不到任何有关变量定义的块范围的证据。
jfriend00

1
@Trung-这是一个非常特殊的情况(仅在catch处理程序中,OP所要求的不太可能,并且不能以任何通用方式用于在ES3中的常规块中创建自己的块范围变量。) OP的问题,然后随时提出自己的答案
jfriend00

12

由于以下原因,未实现块范围:

  1. 它使语言更易于实现。JavaScript最初被设计为用于编写交互式Web应用程序的语言。因此,它必须小巧且易于实现。
  2. 块作用域给动态语言(如JavaScript)带来了性能上的打击。这是因为当您尝试访问不在当前作用域中的某个变量时,JavaScript首先检查当前作用域,然后是父作用域,依此类推,直到找到该变量或到达末尾为止。因此,引入块作用域会使循环和嵌套循环中的变量访问非常缓慢。
  3. 缺少块作用域使编写程序更加容易。例如,假设您只想在满足特定条件时才创建变量。您需要在JavaScript中做的就是在if语句中声明并定义变量。在像C这样的语言中,您将必须在if语句外声明变量,然后在if语句内定义变量。
  4. 由于缺少块范围,因此可以取消声明。这在函数声明的情况下特别有用。例如,请参见以下小提琴:http : //jsfiddle.net/L6SgM/(但是请注意,此示例在Firefox中不起作用)。
  5. 由于JavaScript支持一流的函数表达式,因此我们不需要块作用域。可以使用立即调用的函数表达式来模拟它们。

3
“块作用域会给诸如JavaScript之类的动态语言带来性能上的损失。” -这是实现的属性,而不是语言。也许它适用于第一个JavaScript实现,但是在过去十年中编写的任何引擎都不应该因此而受苦。
Marijn 2013年

#5)严格来说,我们不需要“不需要”块作用域,而首先需要JavaScript ...幸运的是,ECMA团队似乎不同意通过使用'let'关键字添加对块作用域的支持...始终欢迎使用简单的语言构造。
豪尔赫·加西亚

2
I:能否提供给我们证明Brendan Eich出于提到的5个原因未在Javascript中实现块作用域的资源?我怀疑您是将历史原因(#1)与您的原因(#2至#5)混在一起。。。II:#3错误:始终创建变量,只有其初始化是有条件的(请参阅:jsfiddle.net/paercebal/yvwhu7r0)。#4是伪造的("use strict" ;在Chrome中添加会导致错误:)Uncaught SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.。#5是一个肮脏的解决方法。。。。
paercebal

它可以使编写程序更容易,但肯定不能维护它们。
mbomb007 '18

0

原因很多,但想到的一些原因是有助于解析/调试使用对象文字的代码(有时看起来像一个块),并简化局部变量的垃圾收集。

我希望所承诺的支持(例如,在此处讨论,例如http://esdiscuss.org/notes/2012-07-25)能成为现实,因为使用这样的变量非常方便,因为它们i仅在本地单回路。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.