深刻理解let和var的区别(暂时性死区)!!!

首先咱们应该知道js引擎在读取js代码时会进行两个步骤:javascript

  • 第一个步骤是解释。
  • 第二个步骤是执行。

所谓解释就是会先通篇扫描全部的Js代码,而后把全部声明提高到顶端,第二步是执行,执行就是操做一类的。java

咱们先来看个简单的变量提高案例吧

a = 'javascript';
    var a;
    console.log(a);//'javascript'
console.log(b);//undefined
    var b='javascript'

遇到 script 标签的话 js 就进行预解析,将变量 var 和 function 声明提高,但不会执行 function,而后就进入上下文执行,上下文执行仍是执行预解析一样操做,直到没有 var 和 function,就开始执行上下文。如:函数

a=5;
show();
var a;
function show(){};

预解析:code

function show(){};
var a;
a=5;
show();

须要注意都是函数声明提高直接把整个函数提到执行环境的最顶端。ip

那么let/const和var又有什么区别呢??

  • let/const是使用区块做用域;var是使用函数做用域。
  • 在let/const声明以前就访问对应的变量与常量,会抛出ReferenceError错误;但在var声明以前就访问对应的变量,则会获得undefined。
console.log(aVar) // undefined
console.log(aLet) // causes ReferenceError: aLet is not defined
var aVar = 1
let aLet = 2

会出现这样的状况是由于let/const拥有“暂时性死区(TDZ)”。作用域

什么是暂时性死区?

当程序的控制流程在新的做用域(module, function或block做用域)进行实例化时,在此做用域中的用let/const声明的变量会先在做用域中被建立出来,但所以时还未进行词法绑定,也就是对声明语句进行求值运算,因此是不能被访问的,访问就会抛出错误。因此在这运行流程一进入做用域建立变量,到变量开始可被访问之间的一段时间,就称之为TDZ(暂时死区)。io

结论:let/const声明的变量,的确也是有提高(hoist)的做用。这个是很容易被误解的地方,实际上以let/const声明的变量也是会有提高(hoist)的做用。提高是JS语言中对于变量声明的基本特性,只是由于TDZ的做用,并不会像使用var来声明变量,只是会获得undefined而已,如今则是会直接抛出ReferenceError错误,并且很明显的这是一个在运行期间才会出现的错误。console

ES6 规定暂时性死区和let、const语句不出现变量提高,主要是为了减小运行时错误,防止在变量声明前就使用这个变量,从而致使意料以外的行为。这样的错误在 ES5 是很常见的,如今有了这种规定,避免此类错误就很容易啦~function

相关文章
相关标签/搜索