es6 let與var的區別詳解
阿新 • • 發佈:2019-03-23
新特性 筆記 創建 輸出 作用域 習慣 pre ron 設計缺陷 一、前言
說到做到,現在暫時放了放JS模式的讀書筆記,打算好好看看ES6,畢竟出了這麽久了,還是靠JS吃飯的,都不好好學JS新特性,確實說不過去,我本來是想當讀書筆記去記錄ES6,但是這個確實是屬於邊看邊用邊記憶的,所以還是零散的挑重點去記錄吧。
二、let與var的區別
1.let 不能重復申明,var可以
這是最為簡單最容易記憶的一點,當我們使用var申明,是可以反復申明同一個變量的,但並不推薦這個做,因為同名變量的創建對站在內存角度是無意義的,所以let的出現也是為了解決早期JS設計缺陷。
var a = 1; var a = 2;//不會報錯 let b = 1; let b= 2;//報錯
2.let會產生塊級作用域,且只在自己的作用域內生效,var不受限制
什麽是塊級作用域?當我們在{}中使用了let或者const時,{}的範圍就是一個塊級作用域,此時let只能在{}中使用,外部無法訪問。像這樣:
{ let a = 1; var b = 2; } console.log(a);//報錯 console.log(a);//2
或者這樣:
if(true){ let a = 1; var b = 1; } console.log(a); console.log(b);2.1let與var在for循環中的不同表現
//for循環用var var a = []; for (var i = 0; i < 5; i++) { a[i] = function () { console.log(i); }; } a[1]();//5 a[2]();//5 a[3]();//5 //for循環用let var b = []; for (let i = 0; i < 5; i++) { b[i] = function () { console.log(i); }; } b[1]();//1 b[2]();//2 b[3]();//3
在明白上面2個循環的區別之前,我們先來理一理知識點,我們要知道,for循環中設置循環變量的部位其實是一個父作用域,循環體內部是個子作用域。
在父子作用域中同時使用let的情況下,兩個作用域就是互不幹擾的兩個塊級作用域:
{ let a = 1; { console.log(a);//報錯 let a = 2; console.log(a);//2 } console.log(a);//1 }
子作用域不使用let,還是可以正常繼承父作用域,父也能讀取子。
{ let a = 1; { var b = 2; console.log(a);//1 } console.log(a);//1 console.log(b);//2 }
所以下面這個循環輸出了三次echo,因為在子作用域中申明的i跟父作用域中的i可以說是完全不同的兩個i;
for(let i = 0;i<3;i++){ let i = ‘echo‘; console.log(i); };//輸出三次echo
但如果你將let改為var,你會發現只輸出一次,因為沒有了塊級作用域,父子作用域共用了一個變量i,第一次循環後,子作用域的i被改為了echo,父作用域中i<3的判斷無法通過,所以只輸出了一次。
那麽回頭再看看最初的兩個循環,為什麽var申明輸出了3個5,而let輸出了1,2,3呢,嘗試去理解,說到底還是塊級作用域搞的鬼。
3.let不存在變量提升 變量提升可以說是var申明設計不嚴謹的一點,可能我們在開發中已經習慣申明一個全局變量,然後可以在申明前後都可以使用它,這很方便,但是不符合規範。console.log(a);//undefined var a = 1; console.log(b);//報錯 let b = 1;4.let存在暫時性死域 當一個區域存在let申明時,這個區域就形成了一個封閉的作用域,在let申明前使用這個變量就會報錯,也就是只能先申明再使用,這種語法也稱為暫時性死域。
{ let a = 1; { console.log(a);//報錯 let a =2; } }
三、const申明的特點
可以理解為,let的特性const都有,不能反復申明,存在塊級作用域,不存在變量提升,也有暫時性死域的特點。
與let區別在於,const申明的是一個常量,一旦申明就無法修改,let可以,var就更不用說了。
就這樣去記憶吧。
es6 let與var的區別詳解