今天,來探討一下ES6中的塊級作用域。
全局作用域和函數作用域
在ES5中,只全局作用域和函數作用域。這會導致函數作用域覆蓋了全局作用域;亦或者循環中的變量泄露為全局變量。
例如:
// 1.函數作用域覆蓋了全局作用域,發生了變量提升,函數聲明大於var聲明的變量,因此函數里面的a提到了前面,在打印a,初始化一個undefined給a,所以打印出了undefined。
var a = '1';
function fn() {
console.log(a);
if (3<2) {
var a = 3;
}
}
fn(); // undefined
// 2.循環中的變量泄露為全局變量
for(var i=0;i<5;i++) {
console.log(i);
}
console.log(i); // 5;
ES6的塊級作用域
用let命令新增了塊級作用域,外層作用域無法獲取到內層作用域,非常安全明了。即使外層和內層都使用相同變量名,也都互不干擾。
// 1.外層作用域無法獲取到內層作用域
function fn1() {
let a = 41;
if(1 == 1) {
let a = 3;
console.log(2,a); // 2 3
}
console.log(1,a); // 1 41
}
fn1();
{
{
let food = 'apple';
}
console.log(food); // Uncaught ReferenceError: food is not defined
}
{
{
let food = 'apple';
}
console.log(food); // Uncaught ReferenceError: food is not defined
}
// 2. 外層和內層都使用相同變量名,也都互不干擾
{
{
let food = 'apple';
console.log(food); // apple
}
let food = 'orange';
console.log(food); // orange
}
塊級作用域和和函數聲明
在ES5中,函數只能在頂級作用域和函數作用域中聲明,不能在塊級作用域中聲明。但是在ES6中,函數可以在塊級作用域中聲明。
但是會有一定的問題,因為函數聲明會被提到代碼的最前面。所以會報錯,最好在ES6中用函數表達式來表示一個函數。
例如:
//1.函數聲明報錯
{
if (4 < 2) {
function fn() {
console.log('我在函數里面!');
}
}
}
fn(); // Uncaught TypeError: fn is not a function
//2.函數表達式沒錯
{
let fa = '111';
let fn = function () {
console.log('我在函數里面!');
}
console.log(fa,fn); // 111 ƒ () { console.log('我在函數里面!');}
}
注意:ES6中允許函數在塊級作用域中可以聲明的條件是必須在大括號里面,否則就會報錯。
// 1.報錯的情況
if (4>2) {
let fn = function () {};
}
//2.報錯的情況
if (4>2)
let fn = function () {}; // Uncaught SyntaxError: Lexical declaration cannot appear in a single-statement context
最后總結
今天就將這些,下次再會。期待再更新。