ES5 和 ES6:let const var 區別

靈靈7發表於2019-04-07

var

  1. 全域性宣告,全域性作用域有效;
  2. 可重複宣告同一個變數(後面宣告的值會覆蓋前面的宣告)

let

  1. 塊級作用域內有效;
  2. let宣告的變數可以改變,值和型別都可以改變,沒有限制。

var 和 let 用法 區別

1.let命令所在的程式碼塊內有效

ES5只有全域性作用域和函式作用域,沒有塊級作用域,這帶來很多不合理的場景。第一種場景就是你現在看到的內層變數覆蓋外層變數。而let則實際上為JavaScript新增了塊級作用域。用它所宣告的變數,只在let命令所在的程式碼塊內有效

var name = 'zling'     //用var全域性宣告name 值為 ‘zling’

function() {
    var name = 'obama' //再次用 var 宣告 name 值為 'cbiao'
    console.log(name)  //name 返回 'zling'。覆蓋了第一次宣告的值
    break
}

    console.log(name)  //全域性變數的name 值也為 'cbiao'

另外一個var帶來的不合理場景就是用來計數的迴圈變數洩露為全域性變數

var a = [];

for (var i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}

a[6](); // 10

上面程式碼中,變數i是var宣告的,在全域性範圍內都有效。所以每一次迴圈,新的i值都會覆蓋舊值,導致最後輸出的是最後一輪的i的值。而使用let則不會出現這個問題。

var a = [];

for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}

a[6](); // 6

 


const 

  1. 塊級作用域內有效;
  2. const宣告的變數不得改變值,這意味著,const一旦宣告變數,就必須立即初始化,不能留到以後賦值。
const a ;//報錯,一旦宣告變數,應該立即賦值!!

const b = 2;
b = 3//報錯,因為定義常量之後不能成重新賦值!!

對於複合型別的變數,如陣列和物件,變數名不指向資料,而是指向資料所在的地址。const命令只是保證變數名指向的地址不變,並不保證該地址的資料不變,所以將一個物件宣告為常量必須非常小心。

const names = [];
names = [1,2,3] //出錯,因為變數names指向的地址不能發生改變,應始終指向[]所在的地址!!![1,2,3]與[]不是同一個地址
//不會報錯,因為names指向的地址不變,改變的只是內部資料
const names = [];
names[0] = 1
names[1] = 2
names[2] = 3

如果想讓定義的物件或陣列的內部資料也不能夠修改和改變,可以使用object.freeze(names)進行凍結,這樣為物件新增新屬性就不起作用。

除了將物件本身凍結,物件的屬性也應該凍結。下面是一個將物件徹底凍結的函式

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

 

相關文章