块级作用域
定义:是一个语句,将多个操作封装在一起,通常是放在一个大括号里,没有返回值。
为何需要块级作用域?
在ES6之前,函数只能在全局作用域和函数作用域中声明,不能在块级作用域中声明。没有块级作用域导致很多场景不合理:
function block(){
var a = 1;
if(true){
var a = 2;
}
console.log(a) //2
}
block()
function block(){
let a = 1;
if(true){
let a = 2;
}
console.log(a) //1
}
block()
上面的函数有两个代码块,都声明了变量a,运行后输出 1。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量a,最后输出的值才是 2
ES6中的块级作用域:
1、允许块级作用域任意嵌套,外层作用域无法读取内层作用域的变量
{{{{
{let i = 6;}
console.log(i); // 报错
}}}}
上面代码使用了一个五层的块级作用域,每一层都是一个单独的作用域。第四层作用域无法读取第五层作用域的内部变量。
2、内层作用域可以定义外层作用域的同名变量
{{{{
let i = 5;
{let i = 10;}
console.log(i) //5
}}}}
{{{{
let i = 5;
{
let i = 10;
console.log(i) //10
}
}}}}
3、不需要立即执行匿名函数
立即执行函数:
(function() {
var a = 0;
}());
块级作用域:
{
var a = 0;
}
块级作用域中的函数声明
运行环境:ES6浏览器。
可实现的行为:
1、允许在块级作用域内声明函数
2、函数声明类似于var, 即会提升到全局作用域或函数作用域的头部
3、函数声明还会提升到所有块级作用域的头部
function Func() {
console.log('outside');
}
(function() {
var Func = undefined;
if (false) {
function Func() {
console.log('inside');
}
}
Func();
})(); //报错
考虑到环境导致的差异太大,应该避免在块级作用域中声明函数,如果需要,应该写成函数表达式的形式,而不是函数声明语句
let Func= function Func() {
console.log('inside');
};
Func()
ES6的块级作用域允许声明函数的规则只在使用大括号的情况下成立:
'use strict'
if (true) {
function Func1() {} // 不报错
}
if (true)
function Func2() {} // 报错