ES6總結 let / const 和 塊級作用域

塊級作用域

ES5 只有全局作用域和函數作用域, 沒有塊級作用域
ES6 新增塊級作用域概念 一對花括號 {} 即爲一個塊級作用域 if 語句和 for 語句裏面的 {} 也屬於塊作用域

  • 沒有塊級作用域,將帶來很多不合理的場景

內層變量可能會覆蓋外層變量

var tmp = new Date();
function f() {
 console.log(tmp);
 if (false) {
   var tmp = 'helloworld'; 
 }
}
f(); // undefined  ---由於變量提升 導致內層的tmp覆蓋了外層的tmp

循環變量泄露爲全局變量

for (var i = 0; i < 3; i++) {
 console.log(i);
}
console.log(i); // 3
  • 塊級作用域的優勢

立即執行函數

(function(){ })();

//現在一個 {} 就可以代替
{}

外層代碼塊不受內層代碼塊的影響

{
    let a = 1;
    {
        let a = 2;
    }
    console.log(a); //1
}

外層作用域無法讀取內層作用域的變量

{
    {
        let a = 2;
    }
    console.log(a); // ReferenceError: a is not defined
}

let 和 const 特點

  • let 和 const 只在塊級作用域中有效
{
  let a = 1;
  var b = 2;
}
a // ReferenceError: a is not defined
b // 2 

ES6 中 {} 即爲一個塊級作用域 所以在 {} 外面就無法訪問 let 聲明的變量
在 for 循環中使用 let

for(var i = 0; i<3;i++){
    setTimeout(function(){
        console.log(i); // 出3個3
    }, 1000)
}
// var 聲明的變量 i 泄露爲全局變量 當執行 console.log(i) 時 循環已經走完了, i 最終爲 3

for(let j = 0; j<3;j++){
    setTimeout(function(){
        console.log(j); // 依次輸出  0 1 2
    }, 1000)
}
// let 聲明的變量只在本輪循環有效 每次循環都是一個塊級作用域, j 也是一個新的變量
  • let 和 const 不存在變量提升
console.log(a); // undefined
console.log(b); // ReferenceError: b is not defined

var a = 1;
let b = 2;

let 聲明的變量 b 不存在變量提升 所以在聲明之前使用 b 就會報錯
只要塊級作用域內存在let命令,它所聲明的變量就"綁定"這個區域,不再受外部的影響 在語法上稱爲"暫時性死區"(temporal dead zone,簡稱TDZ)

{
    // TDZ開始
    tmp = 'abc'; // ReferenceError: tmp is not defined
    console.log(tmp); // ReferenceError: tmp is not defined
    typeof tmp; // ReferenceError: tmp is not defined
    
    let tmp; // TDZ結束
}
  • let 和 const 不允許重複聲明
{
  let a = 1;
  var a = 2; // SyntaxError: Identifier 'a' has already been declared
}

// 下面例子是不會報錯的,下面有兩個代碼塊, 外層代碼塊不受內層代碼塊的影響
{
    let a = 1;
    {
        let a = 2;
    }
    console.log(a) // 1
}
  • 使用let 和 const聲明的變量不會綁在window對象上
var a = 1;
console.log(window.a); // 1

let b = 1;
console.log(window.b); // undefined

const

  • const 聲明的變量表示只讀的常量 聲明的時候必須賦值
const a; // SyntaxError: Missing initializer in const declaration

const a = 1;
a = 2; // TypeError: Assignment to constant variable.
  • const 只是保證變量名指向的地址不變,並不保證該地址的數據不變
const foo = {};
foo.prop = 123;

foo.prop  // 123

foo = {}; // TypeError: Assignment to constant variable.

const a = [];
a.push('Hello'); // 可執行
a.length = 0;    // 可執行
a = ['Dave'];    // 報錯

//如果真的想將對象凍結,應該使用Object.freeze方法
const foo = Object.freeze({});

foo.prop = 123;
foo.prop // undefined
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章