为什么JavaScript会提升变量?


94

为什么JavaScript会提升变量?

设计师决定实施吊装时的基本原理是什么?还有其他流行的语言可以做到这一点吗?

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


7
一点上,我怀疑这是历史性的,我严重怀疑这与最初的“易于实施”无关。
戴夫牛顿

4
老实说,问布伦丹·艾希(Brendan Eich),他似乎反应灵敏。
Felix Kling

22
这个问题怎么没有建设性?
Francisc

18
@Francisc欢迎堆栈溢出,所有你可以问的就是移动div中的jQuery
Xlaudius

20
这是一个非常重要的问题。应该已经允许了。那不是诱饵。吊装是了解JavaScript如何工作的核心要素之一,“为什么”是在大多数有关该语言的教科书中都可以解决的合法问题。这样的堆栈溢出人员不断脚人们的问题是不对的。
bearvarine

Answers:


55

正如Stoyan Stefanov在“ JavaScript模式”一书中解释的那样,提升是JavaScript解释器实现的结果。

JS代码解释分两次进行。在第一遍中,解释器处理变量和函数声明。

第二遍是实际的代码执行步骤。解释器处理函数表达式和未声明的变量。

因此,我们可以使用“吊装”概念来描述这种行为。


15
我个人真的不喜欢“吊装”这个词。它提供了错误的表示形式,即变量和函数声明已神奇地提升到当前作用域的顶部,而实际上,正如您提到的,JS解释器会在源代码中扫描绑定,然后执行代码。
contactmatt

现在我明白了为什么JS是最容易被误解的语言,在任何教程中我都没有看到。并与吊装(和翻译流程)混淆。
Swapnil Patwa '17

17
嗯,这并不能真正解释其原理。单程口译员(不会导致吊装)要简单得多-那么设计者为什么选择两次通行证呢?
Bergi

1
这并不能解释为什么特别要悬挂变量。函数有意义,变量没有意义(在大多数情况下)-我认为这是一个错误。
乔什·M

Josh M.如此广泛地指定,我不认为这是一个“错误” ...(我同意这个答案虽然并没有真正回答推理)
Jonas Wilms

10

JS创造者Brendan Eich曾经在Twitter上说过

“因此,无功吊装是功能吊装的意外结果,没有块作用域,并且是JS作为1995年的紧急工作。”

他还解释说……

“函数提升允许自上而下的程序分解,在声明前调用'let rec'是免费的; var提升带有标签。

布伦丹·艾希(Brendan Eich)

还有其他流行的语言可以做到这一点吗?

我不知道有其他流行语言以相同的方式提升变量。我认为,甚至ActionScript(Flash开发中使用的ECMAScript的另一种实现)也没有实现提升。对于熟悉其他正在学习JavaScript的语言的开发人员来说,这已成为混乱和沮丧的根源。

更新:根据评论,Python具有类似的变量提升行为


2
给+1,因为这是唯一尝试直接解决该问题的答案。
戴蒙

1
感谢您的回答。我完全同意@Damon!
codingbryan

1
另一个具有可变提升的流行语言是Python:stackoverflow.com/q/63337235/2326961
Maggyero

2

这是因为javascript解释器会在两个周期内解释代码。

  1. 代码完成/编译:
  2. 代码执行:

在第一个循环中,所有变量和函数声明都将置于其正在执行的函数作用域的顶部。这有助于在函数执行之前就创建variableObjectsforexecution context函数。

在第二阶段,按预期方式逐行进行值分配,代码语句和函数调用。

您在这里有一些更详细的阅读

它将使您更好地了解围绕和声明的行为letconst以及class变量和函数之间的优先级。


1
您是否暗示这是设计选择的结果?如果是这样,您应该在答案中清楚说明。但是阅读Brendan Eich的答案,这可能是一个通缉的功能,它取决于您如何解释最后一句话。最重要的是,我仍然不确定为什么
-Bombinosh
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.