变量晋升是每个JS开发人员都据说过的那些术语之一,因为你在搜索引擎上搜寻烦人的谬误,并且最终到StackOverflow上查找时,有人会通知你这个谬误是因为变量晋升(hoisting)导致的。那么,什么是变量晋升呢?(BTW,作用域会在另一篇文章中介绍,我心愿放弃文章小而专一)

如果你是JavaScript老手,那么你可能曾经遇到过一些怪异的行为,比方,有些变量的值会偶尔是undefined、抛出了ReferenceError谬误,等等。变量晋升常常被解释为_将变量和函数放到文件的顶部_。不过,只管变量晋升可能看起来像这样,然而背地并非如此????。

当JS引擎获取咱们的脚本时,它要做的第一件事件就是为咱们代码中的数据设置内存。这时候没有执行任何代码,仅仅是在为执行筹备好所有。函数申明和变量的存储形式是不同的。函数存储的是对整个函数的一个援用

对变量来说,就有所不同了。ES6引入了两个新关键字来申明变量:letconst。用let或者const关键字申明的变量被存储的时候是_未被初始化的_。

var关键字申明的变量以默认值undefined存储。

当初创立阶段曾经实现,咱们能够理论执行代码。上面咱们来看看,如果在文件头部申明函数或者任何变量之前,有三条console.log语句的时候,会产生什么。

既然函数存储的是对整个函数代码的一个援用,那么咱们甚至能够在创立他们的代码行之前调用他们! ????

当咱们在一个用var关键字申明的变量的变量申明之前援用该变量时,它只会返回存储的默认值undefined!不过,这样做有时候会导致不可预期的行为。大多数状况下,这意味着你无心中援用了它(你可能并不想它的值为undefined)????。

为了避免咱们像在用var关键字申明变量时那样一不小心就援用了一个undefined变量,只有咱们试图拜访未被初始化的变量时,就都会抛出一个ReferenceError谬误。变量理论申明之前的“区域”称为暂时性死区:就不让咱们在变量初始化之前援用该变量(这也包含ES6类!)。

当引擎通过咱们理论申明变量的行时,内存中的值就被咱们理论申明它们的值笼罩。

搞定! ????上面咱们疾速回顾一下:

  • 在执行代码之前,将函数和变量存储在内存中以用于执行上下文。这称为变量晋升(hoisting)
  • 函数被存储为一个对整个函数的援用,用var关键字申明的变量的值为undefined,而用letconst关键字申明的变量未被初始化。

心愿本文能让你搞清楚变量晋升(hoisting)这个术语。

原文 by lydia hallie:https://dev.to/lydiahallie/javascript-visualized-hoisting-478h
本文由博客一文多发平台 OpenWrite 公布!