JavaScript中没有块级作用域经常会导致理解上的困惑,在其他类C的语言中,由花括号封闭的代码都有自己的作用域,因而支持根据条件来定义变量。但是在JavaScript中下面的代码并不会得到想象中的结果:
if(true){
var aa = 'red';
}
console.log(aa);//red
这里在if
语句中定义了一个变量aa
,如果是在C、C++或Java中,aa
会在if
语句执行完毕后被销毁。但在JavaScript中,if
语句里的变量声明会将变量添加到当前的执行环境,而JavaScript中的执行环境通常只有两种——全局执行环境和局部执行环境,局部执行环境一般就是函数,所以这里的aa
是定义在全局执行环境中,也就是作为window对象的属性存在的,如下图:
所以根据作用域链机制会正常打印red
。
没有块级作用域是个缺点,好在ES6把这个问题解决了,新标准中引入了关键字let
,支持了块级作用域,看下面代码:
if(true){
let aa = 'red';
console.log(aa);//red
}
console.log(aa);//Uncaught ReferenceError: aa is not defined
改用let
声明变量aa
,在if
块里面可以访问aa
,外面就报错了。
由下图也可以看出,aa
并没有被声明在window
上,而是在全局作用域Global
的前端增加了一个Block
作用域,而Block
正是块的意思,根据作用域链机制可以在if
块内部访问到aa
。
所以如果用的是ES5,那是没法使用块级作用域的。ES6出来有几年了,浏览一下各主流明星互联网公司的招聘需求,基本都要求熟悉ES6标准,建议读者们都学习一下。