在学习js的作用域时有一个非常有意思的例子:
<script type="text/javascript">
var x = 1;
function rain(){
alert( x ); //弹出 'undefined',而不是1
var x = 'rain-man';
alert( x ); //弹出 'rain-man'
}
rain();
</script>
产生这种结果的原因是在js中,局部变量x的作用域是函数作用域,也就是说它在一开始就已经被声明了,此时程序并不会去寻找全局变量x,而是寻找局部变量x,但此时局部变量x还未被初始化,因此会得到undefined的结果。这种声明的特性可以称之为“变量提升”。
JavaScript中使用let和const关键字来实现块级作用域。
let
let关键字声明主要有两个特点
- 声明的变量是局部的,但为了与同样是局部的函数作用域区别,称之为块级作用域,同时包含了变量的作用域只在所属大括号包围(块)内的含义
- 声明不具有“变量提升”的特性,而是称之为“暂时性死区”特性
例如上面的例子:
// 特点1
function rain(){
let x = 'rain-man';
}
alert( x ); // Error: x is not defined
// 特点2
function rain(){
alert( x ); // Error: x is not defined
let x = 'rain-man';
alert( x );
}
rain();
第二个例子说明,程序一样知道rain函数中声明了x,但let的块级作用域特性使其忽略掉了该声明,报出了变量未声明的错误,否则就是“变量提升”。
const
与let类似,只不过const另外有一层与强类型语言相似的含义,即变量为常量,必须在声明时初始化,且值不能被改变。