ES6學習之路(一) let與const

let and const

相同點:
let與const用來聲明變量,用法與var類似,但是let與const聲明的變量只在它們命令所在的代碼塊中有效;

let與const聲明的變量不存在變量提升,所以必須在聲明後使用,否則會報錯,沒有賦值會輸出undefined;

//變量聲明前調用會報錯
console.log(a)//報錯
let a=0;
console.log(a)//0
//變量聲明未賦值返回Undefined
let a;
console.log(a)//undefined

如果在塊級作用域中存在用 let和const聲明的變量,那麼這些變量必須在let和const聲明後執行,否則就會報錯;阮一峯老師稱之爲“暫時性死區”

let tmp=0;
if(true){
    //在本作用域中已有tmp的聲明,需要在聲明後使用,否則報錯;
    tmp=5;//報錯
    let tmp;
    console.log(tmp)//undefined
    tmp=123;
    console.log(tmp)//123
}

let和const不允許在同一作用域中,重複聲明同一個變量

{
    //重複聲明會報錯
    let a=0;
    var a=5;//Identifier 'a' has already been declared

    let b=0;
    b=5;//Identifier 'a' has already been declared
}

不同點:
const聲明一個只讀的常量,一旦聲明常量值不能改變;用const聲明必須馬上賦值 否則報錯;

    //const 必須聲明後必須馬上賦值 不然會報錯
    const a;//Missing initializer in const declaration

    //聲明後對於簡單數據類型來說,值是不能改變的(常量),否則就會報錯;
    const a=10;
    a=20;//Assignment to constant variable.

const所聲明的變量對於簡單的數據類型(數值,字符串,布爾值)來說算是固定的常量,但是對於複合類型的數據(對象,數組)來說,const只能保證這個變量指向的內存地址不變,對象的值與數組的值還是可以修改的。

    const foo={};
    foo.prop=123;
    console.log(foo.prop)//123

上面代碼就是修改了foo這個變量的prop屬性的值,因爲prop屬性屬於foo這個對象,使用的是foo的內存地址,所以const不會報錯;

但是,如果試圖去修改foo對象的話就會報錯;

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

數組同理

//調用屬性不會報錯
const arr=[];
arr.push('hello');
arr.length=0;
    //想要修改對象就會報錯
    const arr=[];
    arr=[];//TypeError: Assignment to constant variable.

let&for循環

for循環中 如果用var來初始化i的值,聲明的是一個全局的變量i;
用let來聲明i,每次循環都會創建一個新的變量i;

//使用var初始化變量
var arr=[];
for(var i=0;i<10;i++){
    arr[i]=function (){
    console.log(i)
    }
}
arr[6]()//10

上面代碼中,變量i是var命令聲明的,在全局範圍內都有效,所以全局只有一個變量i。每一次循環,變量i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),裏面的i指向的就是全局的i。也就是說,所有數組a的成員裏面的i,指向的都是同一個i,導致運行時輸出的是最後一輪的i的值,也就是10。

如果使用let,聲明的變量僅在塊級作用域內有效,最後輸出的是6。

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

上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變量,所以最後輸出的是6。你可能會問,如果每一輪循環的變量i都是重新聲明的,那它怎麼知道上一輪循環的值,從而計算出本輪循環的值?這是因爲 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上進行計算。

另外,for循環還有一個特別之處,就是設置循環變量的那部分是一個父作用域,而循環體內部是一個單獨的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

上面代碼正確運行,輸出了3次abc。這表明函數內部的變量i與循環變量i不在同一個作用域,有各自單獨的作用域。
(上面是學習阮一峯老師的ES6入門記錄下來的)

發佈了48 篇原創文章 · 獲贊 17 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章