关键字 let
和 const
创建的变量的作用域都是 「 块级作用域 」 ( block scoped ) 。「 块级作用域 」就是 「 变量只存在于声明位置开始开始的当前块以及所有子块中,包括内部函数和匿名函数 」 。
只存在于声明位置开始的当前块中
以下代码演示了 const
声明的变量 tmp
仅存在于 if 语句的块中
function func() { console.log(tmp); if (true) { const tmp = 123; } } func()
报错如下
Uncaught ReferenceError: tmp is not defined
放在当前块范围之后也是会继续报错的
function func() { if (true) { const tmp = 123; } console.log(tmp); } func()
报错如下
VM164:5 Uncaught ReferenceError: tmp is not defined
与之相比较, var
的作用域是函数级别的,也就是所有变量的声明都会提升到函数的顶部,例如瞎 main的代码,就会正确输出
function func() { console.log(tmp); if (true) { var tmp = 123; } console.log(tmp); } func()
输出结果如下
undefined 123 undefined
注意:声明变量和定义变量 ( 赋值或初始化 ) 是不一样的。声明只是说这个变量存在,例如 var tmp
、let tmp
、const tmp
。而定义变量,就是给该变量一个初始值 ( 赋值或初始化 ),例如 tmp = 3
、tmp=3.1415967
。声明和初始化可以合在一起,例如 let tmp = 123
。学过 C 语言 的应该对此了解比较透彻。
一直存在于子块中,除非被显式的覆盖
function func() { const foo = 5; function hello() { console.log(foo); // 10 } hello(); console.log(foo); // 5 } func();
运行结果如下
5 5
块级作用域的最大好处
块级作用域的最大好处就是 「 可以在不同的块层级中隐藏变量」,例如下面的代码,最后一个输出是 5
而非 10
function func() { const foo = 5; if ( foo ) { const foo = 10; // 隐藏外部的 `foo` console.log(foo); // 10 } console.log(foo); // 5 } func();
输出结果为
10 5
不要诧异,因为 const
的作用域是块级别的,所以再每个块级别中可以声明一个变量来覆盖上一级别中的同名变量
目前尚无回复