JS的变量提升

Hoisting的定义首先 , 看看mdn对它的解读:

变量提升(Hoisting)被认为是 ,  JAVAscript中执行上下文 (特别是创建和执行阶段)工作方式的一种认识 。在 ECMAScript® 2015 Language Specification 之前的JavaScript文档中找不到变量提升(Hoisting)这个词 。不过 , 需要注意的是 , 开始时 , 这个概念可能比较难理解 , 甚至恼人 。
我们可以理解成 , 在编译的阶段 , js引擎帮我们把变量和函数的声明放在最前面 , 但实际上变量和函数声明在代码里的位置是不会动的 。
知道了个大概后 , 我们从流程上来说说吧 。
创建阶段当JS引擎得到我们的脚本时 , 它做的第一件事就是为我们代码中的数据设置内存 。在这一点上没有执行任何代码 , 它只是在为执行准备一切 。函数声明和变量的存储方式是不同的 。函数是以对整个函数的引用来存储的 。
JS的变量提升

文章插图
 
流程1
我们可以看到图中的内容 , 但是如果这个时候 , 遇到了变量会怎么样呢 , 尤其是ES6中的const和let,让我们接着往下看:
JS的变量提升

文章插图
 
流程2
从图中我们可以总结出来 , 用let , const声明的变量以uninitialized来存储的 。
这里就解释了 , 为什么我们用let和const声明的 , 不能在它之前使用 , 也就是暂时性死区 。
那用var关键字来声明的话 , 结果你猜到了嘛 , 我们来看图:
JS的变量提升

文章插图
 
流程3
【JS的变量提升】很显然 , 我们发现 , 用var关键字声明的变量是以默认值undefined来存储的 。
这里是平时面试会被问到的一个考点 , 现在看来不过如此 。
小结一下,他们的区别:
  • 用var关键字声明的变量是以默认值undefined来存储的 。
  • 用let , const声明的变量以uninitialized来存储的 。
现在 , 创建阶段已经完成 , 我们可以实际执行代码了 。
让我们看看 , 如果我们在声明函数或任何变量之前 , 在文件顶部有3个console.log语句 , 会发生什么 。


    推荐阅读