原文链接:https://medium.com/better-programming/hoisting-in-javascript-6af97650dbb2
如果你是萌新,”变量提升”在JavaScript是一个难以理解的知识点。它几乎困惑了所有人。不要担心,我将会帮助你理解在JavaScript中”变量提升”工作机制。
什么是变量提升?
“变量提升”是移动所有定义到当前作用域顶部的JavaScript默认行为。
JavaScript没有提升以下项目:
- 1.用表达式定义的函数
- 2.用let或者const定义的变量和常量
- 3.箭头函数
在JavaScript中,一个变量可以被使用在它被定义之前。
1 | x = 5; |
好的…,但这是什么意思?我没有理解你要说的。
让我来通过几个新例子帮助你理解
1 | // Example 1 |
当一个函数定义被提升的时候整个函数体将被提升。因此解释完成第一个示例代码之后,它更像这样运行:
1 | unction foo(){ |
But… isn’t the code after a return statement unreachable?(这句有点看不懂)
在JavaScript执行中,有上下文( ECMA 5 分为词法环境,变量环境,和绑定this指针)和进程(一组按顺序调用的语句)。当进入执行作用域时,定义贡献变量环境。它与语句不同的是它不受进程规则的限制。
让我们再看一个例子,这次是一个函数表达式。
1 | // Example 2 |
注意到当变量被创建时初始化是undefined。具有”初始值”的变量实在执行时分配表达式的值,而不是变量被创建的时候。
1 | var myFunction = function () { |
在上面的代码片段中,左边的var myFunction是一个变量声明定义。
变量声明得到提升,但是他的分配表达式没有提升。所以,当myFunction被提升的时候,解释器初始化设置var myFunction = undefined。函数定义没有提升。
记住上面所有的知识点,然后让我们来看下例2如何工作的。
它运行就像这样:
1 | function foo(){ |
在调用第一个函数表达式后,第二个函数表达式无法访问。
在顶部声明你的变量以免混乱
变量提升非常有趣但它可能会导致bug,因为十分容易被忽略。
你可以使用严格模式,在顶部使用use strict指令。JavaScript严格模式下不允许使用还没有定义的变量。