我们习惯将 var a = 2;
看作一个声明,而实际上 JavaScript 引擎并不这么认为。它将 var a
和 a = 2
当作两个单独的声明,第一个是编译阶段的任务,而第二个是执行阶段的任务。
这意味着无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。可以将这个过程形象成所有声明(变量和函数)都会被「移动」到各自作用域的最顶端,这个过程被称为提升。
任何声明在某个作用域内的变量,都将附属域这个作用域,而每个作用域都会进行提升操作。
先有「声明」,后有「赋值」
**只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。**如果提升改变了代码执行的顺序,会造成非常严重的破坏。
提升是指声明会被视为存在于其所出现的作用域的整个范围内。
使用let进行的声明不会在块作用域中进行提升,声明的代码在运行之前,声明并不存在。
函数声明和变量声明都会被提升。
避免重复声明:在存在多个「重复」声明的代码中,特别是当普通的 var 声明和函数声明混合在一起的时候,函数会首先被提升,然后才是变量。