在 ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
我们先来看一下下面这种情况:内层变量可能会覆盖外层变量。
var txt = '外层变量-->你好呀';function fn() {console.log(txt);if (false) {var txt = '内层变量-->hello';}
}fn();//undefined
上面代码的原意是,if
代码块的外部使用外层的 txt 变量,内部使用内层的 txt 变量。但是,函数 fn 执行后,输出结果为undefined
,原因在于变量提升,导致内层的 txt 变量覆盖了外层的 txt 变量。
ES6 的块级作用域
let
实际上为 JavaScript 新增了块级作用域
let txt = '外层变量-->你好呀';function fn() {console.log(txt);if (false) {let txt = '内层变量-->hello';}
}fn();
上面的函数有两个代码块,都声明了变量 txt,运行后输出 '外层变量-->你好呀'。这表示外层代码块不受内层代码块的影响。
块级作用域与函数声明
这个这就不多做解释了,因为用到的不是很多,没有什么必要深入了解,这里就简单说一下
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
而ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let
,在块级作用域之外不可引用。
function fn() {console.log('哈哈哈');
}(function() {if (false) {// 重复声明一次函数fnfunction fn() {console.log('啦啦啦');}}f();
}());
上面这段代码是 ES6 的写法,但是如果在 ES5 中运行也是能出来的
因为浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际都能运行,不会报错。