JS变量声明提高

首先来看一段代码javascript

console.log(a)
var a = 2;
输出结果是2,正常来讲JS若是是逐行向下执行,那么应该输出undefined,为什么此处输出2呢?

缘由在于JS在执行前都会进行编译(一般就在执行前),在编译过程当中包括变量和函数在内的全部声明都会被处理。java

定义

是指在 JavaScript 代码执行前的编译过程当中,JavaScript 引擎把变量的声明部分和函数的声明部分提高到代码开头的“行为”。变量被提高后,会给变量设置默认undefined。浏览器

那let,const是否会进行变量声明提高呢?

首先咱们要知道定义一个JS变量分为三个阶段svg

  • 建立create
  • 初始化initialize
  • 赋值assign

下面咱们分别来看看var、let、function 和 const的过程函数

var声明

function fn() {
  var x = 1;
}
fn();
  • 进入 fn,为 fn 建立一个环境。
  • 找到 fn 中全部用 var 声明的变量,在这个环境中「建立」这些变量(即 x 和 y)。
  • 将这些变量「初始化」为 undefined。
  • 开始执行代码
  • x = 1 将 x 变量「赋值」为 1

 由以上步骤可知,var 声明会在代码执行以前就将建立变量,并将其初始化为 undefined。即建立和初始化会被提高spa

function声明

fn();
function fn() {
  console.log(1);
}
  • 找到全部用 function 声明的变量,在环境中「建立」这些变量。
  • 将这些变量「初始化」并「赋值」为 function(){ console.log(1) }。
  • 开始执行代码 fn2()

由以上步骤可知,function 的「建立」「初始化」和「赋值」都被提高了3d

let声明

{
  let x = 1;
  x = 2;
}
  • 找到全部用 let 声明的变量,在环境中建立这些变量
  • 开始执行代码(注意如今尚未初始化)
  • 执行 x = 1,将 x 初始化为 1(这并非一次赋值,若是代码是 let x,就将 x 初始化为 undefined)
  • 执行 x = 2,对 x 进行赋值

由以上步骤可知,let只有建立过程会提高,初始化和赋值都不会提高,因此会造成暂时性死区,这也是为何在定义前使用let会抛错。code

暂时性死区,就是不能在初始化以前,使用变量cdn

const声明

{
    console.log(x);
  const x = 1;
}
  • 找到全部用 const声明的变量,在环境中「建立」这些变量
  • 开始执行代码(注意如今尚未初始化)
  • 执行x = 1, 将x初始化为1

由以上步骤可知,const的建立过程也会提高,可是与let不一样之处在于const只有建立和初始化两个过程,没有赋值过程。若不初始化则会直接抛错对象

总结

  • var 的建立初始化都被提高了。
  • function 的建立、初始化赋值都被提高了。
  • let 的建立被提高了,可是初始化和赋值没有提高。
  • const的建立被提高可是初始化没提高。const没有赋值。

注意⚠️

函数优先

何为函数优先,来看一下下面的代码👇

foo();
var foo;
function foo() {
  console.log(1)
}

实际上输出值会是1,由于当变量声明和函数声明同时存在时,函数声明优先于变量声明,即函数声明会覆盖变量声明。缘由在于函数的赋值过程也会提高。那有人可能有疑问,若是将var变成let呢?结果为foo不容许被重复声明。

变量提高的存储位置

执行上下文中存在一个变量环境的对象(Viriable Environment),该对象中保存了变量提高的内容。而let,const则存在词法环境中。

浏览器原理与实践

https://www.jianshu.com/p/0f49c88cf169

相关文章
相关标签/搜索