首先来看一段代码javascript
console.log(a) var a = 2;
输出结果是2,正常来讲JS若是是逐行向下执行,那么应该输出undefined,为什么此处输出2呢?
缘由在于JS在执行前都会进行编译(一般就在执行前),在编译过程当中包括变量和函数在内的全部声明都会被处理。java
是指在 JavaScript 代码执行前的编译过程当中,JavaScript 引擎把变量的声明部分和函数的声明部分提高到代码开头的“行为”。变量被提高后,会给变量设置默认undefined。浏览器
首先咱们要知道定义一个JS变量分为三个阶段svg
下面咱们分别来看看var、let、function 和 const的过程函数
function fn() { var x = 1; } fn();
由以上步骤可知,var 声明会在代码执行以前就将建立变量,并将其初始化为 undefined。即建立和初始化会被提高spa
fn(); function fn() { console.log(1); }
由以上步骤可知,function 的「建立」「初始化」和「赋值」都被提高了3d
{ let x = 1; x = 2; }
由以上步骤可知,let只有建立过程会提高,初始化和赋值都不会提高,因此会造成暂时性死区,这也是为何在定义前使用let会抛错。code
暂时性死区,就是不能在初始化以前,使用变量cdn
{ console.log(x); const x = 1; }
由以上步骤可知,const的建立过程也会提高,可是与let不一样之处在于const只有建立和初始化两个过程,没有赋值过程。若不初始化则会直接抛错对象
何为函数优先,来看一下下面的代码👇
foo(); var foo; function foo() { console.log(1) }
实际上输出值会是1,由于当变量声明和函数声明同时存在时,函数声明优先于变量声明,即函数声明会覆盖变量声明。缘由在于函数的赋值过程也会提高。那有人可能有疑问,若是将var变成let呢?结果为foo不容许被重复声明。
执行上下文中存在一个变量环境的对象(Viriable Environment),该对象中保存了变量提高的内容。而let,const则存在词法环境中。
浏览器原理与实践