ES5 只有全局作用域和函数作用域,没有块级作用域,这导致很多场景不合理。
第一种场景:内层变量可能会覆盖外层变量。
var tmp = new Date();
function f(){
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); //undefined
第二种场景:用来计数的循环变量泄露为全局变量。
var s ='hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5 变量i只用来控制循环,但是循环结束,并么有消失,而是泄露了全局变量。
ES6的块级作用域
let实际上为JavaScript新增了块级作用域。
function f1(){
let n =5;
if (true) {
let n = 10;
}
console.log(n); //5
}
ES6允许块级作用域的任意嵌套。
{{{let in = 'hello'}}};
内层作用域可以定义外层作用域的同名变量。
{{
let in = 'hello';
{let in = 'hello'}
}};
块级作用域与函数声明
ES5规定函数只能在顶层作用域和函数作用域值中声明,不能在块级作用域声明。
ES6引入块级作用域,明确允许在块级作用域之中声明函数。ES6规定,在块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
注意的事项:ES6的块级作用域允许声明函数的规定只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
do表达式
块级作用域是一个语句,将多个操作封装在一起,没有返回值。
使用块级作用域可以变为表达式,即可以返回值,办法是在块级作用域之前加上do,是它变为do表达式。
let x = do{
let t =f();
t * t + 1;
} //变量x会得到整个块级作用的返回值。