为什么JavaScript会提升变量?

140

为什么JavaScript会提升变量?

设计师在决定实现变量提升时的理由是什么? 还有其他流行的语言也这样做吗?

请提供相关文档和/或记录的链接。


9
我怀疑现在的情况是历史性的,而且我真的不认为最初它会有其他任何理由,除了“易于实现”。 - Dave Newton
4
老实说,问问 Brendan Eich,他似乎很乐意回应。 - Felix Kling
26
这个问题为什么“不”具有建设性? - Francisc
23
@Francisc 欢迎来到 Stack Overflow,这里你可以询问有关使用 jQuery 移动 div 的问题。 - Xlaudius
32
这是一个非常重要的问题。它本应该被允许。它不是挑衅性言论。Hoisting 是理解 JavaScript 工作原理的核心元素之一,“为什么”是大多数教材中都有涉及的一个合法问题。Stack Overflow 的人们经常这样压制人们的问题,这是不可以的。 - bearvarine
显示剩余12条评论
3个回答

66
如Stoyan Stefanov在《JavaScript Patterns》一书中所解释的那样,变量提升是JavaScript解释器实现的结果。
JS代码解释分两个阶段进行。在第一阶段中,解释器处理变量和函数声明。
第二阶段是实际的代码执行步骤。解释器处理函数表达式和未声明的变量。
因此,我们可以使用“变量提升”概念来描述这种行为。

19
我个人非常不喜欢"hoisting"这个词。它让人产生了一个错误的印象,即变量和函数声明会神奇地被提升到当前作用域的顶部,而实际上,正如你所说,JS解释器会先扫描绑定,然后再执行代码。 - contactmatt
29
这并没有很好地解释原理。一个单遍解释器(不会导致提升)会简单得多——那么为什么设计者选择了两遍扫描? - Bergi
1
这并没有解释为什么变量会被提升,特别是在大多数情况下函数是有意义的,而变量不是--我认为这是一个错误。 - Josh M.
1
我给了这个回答-1分,因为它没有回答问题。 - codingbryan
2
这个答案并没有真正解释为什么设计者决定实现提升,只是解释了提升的原因。所以我也会给一个-1。正如@gfullam提到的另一个答案,"提升"的结果可能是无意的。 - Jswq
显示剩余2条评论

50

JS的创造者Brendan Eich曾经在社交媒体平台Twitter上说过…

"变量提升是函数提升的一个无意的结果,没有块级作用域,JS是1995年匆忙完成的。"

他接着解释道…

"函数提升允许自顶向下的程序分解,'let rec'是免费的,可以在声明之前调用;变量提升也随之而来。"

Brendan Eich

有没有其他流行的语言也这样做呢?
我不知道还有哪些其他流行的语言以同样的方式提升变量。我认为即使是ActionScript——另一种在Flash开发中使用的ECMAScript实现——也没有实现变量提升。对于熟悉其他语言并正在学习JavaScript的开发人员来说,这一点常常会引发困惑和沮丧。

6
点赞,因为这是唯一试图直接回答问题的答案。 - Damon
2
感谢您的回答。我完全同意@Damon! - codingbryan
1
另一种具有变量提升的流行语言是Python:https://dev59.com/questions/wLzpa4cB1Zd3GeqPO6bL - Géry Ogam
3
不正确。Python没有变量提升。参见:https://discuss.python.org/t/why-does-python-have-variable-hoisting-like-javascript/4944/3。 - Victor Yan
1
有趣的是那条推文的后续,它解释了什么是“let rec”,链接为https://dev59.com/DWQn5IYBdhLWcg3w1qEc。 - Gruber

3
这是因为JavaScript解释器在两个周期中解释代码。
  1. 代码完成/编译:
  2. 代码执行:
在第一个周期中,所有变量和函数声明都被带到它正在执行的函数范围的顶部。这有助于在执行之前为函数的执行上下文创建变量对象。
在第二阶段,值分配、代码语句和函数调用按预期方式逐行进行。
您可以在这里进行更详细的阅读。
它将为您提供有关let、const和class声明的行为以及变量和函数之间的优先级的更好的图片。

1
你是在暗示这是设计选择的结果吗?如果是,你应该在回答中清楚地说明。但是根据Brendan Eich的回答,这可能是一个想要的功能,这取决于你如何解释最后一句话。总之,我仍然不确定为什么。 - Bombinosh

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