吊装是JavaScript中的一个关键概念,如果您不知道它的工作原理,可能会导致代码中的意外行为。
javaScript提升是指解释器在执行代码之前将函数,变量或类声明移至其范围顶部的过程。 em>
提升变量
- 如果您在第一次使用后声明一个变量,则此变量声明被“吊起”到其范围的顶部。
- 如果将值分配给变量,则分配的顺序不变,并且不受吊装的影响。
请参阅以下简单示例。
function myFunction() {
console.log(myHoistedVariable); // undefined for ES5 and below
var myHoistedVariable= 1;
console.log(myHoistedVariable); // 1
}
-
由于悬挂了
myHoistedVariable
的声明,因此第一个console.log
将尝试打印出值(注意。实际结果会有所不同,具体取决于您是否使用var
,let or let or const或const) -
console.log
将在值1的分配中打印不确定,而与吊装并没有移动(注意。这是仅使用var
的es5)。
上面的示例基本与以下代码相同:
function myFunction() {
var myHoistedVariable
console.log(myHoistedVariable); // undefined for ES5 and below or ReferenceError for ES6 `let` or `const`
myHoistedVariable = 1;
console.log(myHoistedVariable); // 1
}
注意。 es5vâes6
从技术上讲仍然发生在ES6上,但在实际效果中,您将无法使用它。
- es5:如果您使用的是var,则吊装值将返回未定义。此行为称为MDN。
- es6:对于Let and Const声明,也将其悬挂在其范围的顶部,但并未以未定义的价值初始化。
实际上,这意味着您不能在声明之前使用let或const变量,否则您将获得参考。这称为MDN的Type 3提升行为。
如果您声明具有“使用严格”的JavaScript文件;这将意味着使用VAR升起将抛出3型参考器。 (有关更多信息,请参见this article from Digital Ocean)
提升功能
功能提升变得更加有趣:
- 功能声明将其悬挂在其范围的顶部。这意味着您可以在声明函数之前调用功能。
myHoistedFunction();
function myHoistedFunction() {
console.log("Hi I'm hoisted!");
}
- 函数表达式不悬挂。这意味着,如果您使用const声明函数表达式或在此声明之前无法调用该函数。箭头功能也是这种情况,因为它们也是函数表达式。
为什么根本提升?
如果这一切似乎都非常随机且不必要,那么它也对我来说也是如此 - 尤其是吊装变量。
您为什么不只是强制每个人在其范围的顶部声明变量,功能和课程?即使这在ES6中得到了很大的纠正,并且作为常规规范的功能表达式(另一天的另一个热门话题)。
历史原因
进一步挖掘这一点,我从档案中找到了这推文:
因此,@aravind030792 var升起是功能提升的意想不到的后果,没有块范围,JS作为1995年的冲刺工作。 es6'let'可能会有所帮助。
brendaneich(@brendaneich)October 15, 2014
这个article on Quora进一步解释了这一点。 ** tl; dr ** Brendan Eich在10天内实施JavaScript(又名Livescript)时,希望避免使用ML语言的劳动声明上的痛苦到底执行诸如LISP之类的函数声明。
。布伦丹还跟进了以下推文,澄清了VAR吊装是无意的:
因此,@aravind030792 var升起是功能提升的意想不到的后果,没有块范围,JS作为1995年的冲刺工作。 es6'let'可能会有所帮助。
brendaneich(@brendaneich)October 15, 2014
从这种情况下 - 该功能确实有意义。
口译表绩效原因
当JavaScript引擎编译代码时,它首先经过一个称为解析的过程,将代码分解为较小,更易于管理的部分。
通过将函数声明移动到执行前的范围顶部,解释器可以避免在调用函数时搜索声明的声明。相反,它可以直接从内存执行该函数,该函数可以更快,更高效。
总而言之,似乎有两个关键好处:
-
允许您在定义函数声明之前使用它们。这使您可以组织放置功能代码的位置,无论将其称为何处,只要它们在同一范围内。
-
提高解释器的性能。由于可变声明在编译过程中移至其范围的顶部,因此可能会减少JavaScript引擎解析代码所需的时间。
关于与主题相关的提升/阅读材料的一些重要资源: