var 与let/const 变量提升与TDZ

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38102188/article/details/83651244

我们都知道,在ES5及以前,var关键字被用来定义变量,但是到了ES6,就开始使用let/const来定义变量或者常量。那么这两者到底有什么区别呢?

  1. var遵循函数作用域,let/const遵循块级作用域;
  2. 由于变量提升,var关键字定义的变量在申明之前可以访问,但得到undefined, let/const关键字定义的变量在申明之前访问会抛出ReferenceError的错误。

第一点没什么可讲的,作用域不同而已。下面主要来谈谈第二点。那么为什么 let/const关键字定义的变量在申明之前不能被访问呢,它是不是没有进行变量提升呢?

根据ES6标准中对于let/const声明的章节13.3.1let/const声明,有以下的文字说明:

The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated.
也就是说其实let/const申明的变量,js引擎对其进行预编译时也会进行变量提升(hoist),但是这时候并没有进行词法绑定,也就是对声明语句进行求值运算,是不可以被访问的,访问就会抛出错误,这也被称为暂时性死区(TDZ),如以下代码段:
let total = 0;
function func(num1, num2) {
      console.log(total);   //出现TDZ,访问抛出ReferenceError错误
      let total = num1 + num2;
      console.log(total);
  }
func(100 , 200);
console.log(total);

在这里插入图片描述
那么这时如果把let换成var呢,会出现什么现象呢?

var total = 0;
function func(num1, num2) {
      console.log(total);  
      var total = num1 + num2;
      console.log(total);
  }
func(100 , 200);
console.log(total);

在这里插入图片描述
也就是变量的查找会先在局部作用域内进行,如果没有,才会追溯到上级作用域。由于变量提升的作用,func函数内第一次打印total会打印出undefined, 而不是0,也并不会抛出任何错误。

总结:养成良好的代码习惯,变量的使用遵循先声明再使用的规则,就不会遇到这些问题。

猜你喜欢

转载自blog.csdn.net/m0_38102188/article/details/83651244