在ES6的新特性中,最容易看到TDZ作用就是在let/const的使用上,let/const与var的主要不同有两个地方:
let/const是使用区块作用域;var是使用函数作用域
const
当声明时不赋值报错
const a;
当试图改变const常量时报错
const a=1;
a=2;
在同一作用域中重复定义报错
const a=1;
const a=2;
不会被声明提前(与var有区别)
console.log(a)
const a=2;
var
var定义的变量可以修改,如果不初始化会输出undefined,不会报错
var a
console.log(a) // undefined
var a = 1;
// var a;//不会报错
console.log('函数外var定义a:' + a);//可以输出a=1
function change(){
a = 4;
console.log('函数内var定义a:' + a);//可以输出a=4
}
change();
console.log('函数调用后var定义a为函数内部修改值:' + a);//可以输出a=4
let
let是块级作用域,函数内部使用let定义后,对函数外部无影响
let 声明的变量只在 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。
在let/const声明之前就访问对应的变量与常量,会抛出ReferenceError错误
funcon console.log(a) // ReferenceError: a is not defined
let a
let c = 3;
console.log('函数外let定义c:' + c);//输出c=3
function change(){
let c = 6;
console.log('函数内let定义c:' + c);//输出c=6
}
change();
console.log('函数调用后let定义c不受函数内部定义影响:' + c);//输出c=3
暂时性死区
let 块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}