版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38102188/article/details/83651244
我们都知道,在ES5及以前,var关键字被用来定义变量,但是到了ES6,就开始使用let/const来定义变量或者常量。那么这两者到底有什么区别呢?
- var遵循函数作用域,let/const遵循块级作用域;
- 由于变量提升,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,也并不会抛出任何错误。
总结:养成良好的代码习惯,变量的使用遵循先声明再使用的规则,就不会遇到这些问题。