第二节:ES6新增了let关键字,干嘛用的?
? ? ? ? 大白話,講編程,連載的第一節,得到大家的認可和贊賞,謝謝支持。文章還出現了幾個錯別字,慚愧!此外,連載的頻率初定為每周2節,時間大約在早上10:00;大家對此有何建議都可以留言,前端君都會回復。
? ? ? ? 來吧,開始本節的學習!
????????ES6 給開發者帶來很多令人激動的特性,其中let關鍵字就是其中之一。
? ? ? ? 那么,let關鍵字是什么東西?
let 的用途
????????我們回想一下,我們平時在寫代碼的時候,用var來聲明一個變量,除此之外,好像也沒用其他的關鍵字了,不管我們聲明的是字符串類型、數組類型還是數字類型等,都用一個var 搞掂(因為JavaScript擁有動態類型),很方便。但現在,ES6告訴你,除了var,不妨試試用let來聲明變量試試看。
????
????????咦,這么說,let關鍵字是用了聲明變量的咯?是的,let的用途就是用來聲明變量的。
? ? ? ? 那么,let關鍵字是什么東西?
????????好端端的用var聲明就可以了,為什么要用新的let關鍵字來聲明啊?難道用var有什么不足的地方嗎?是的,還真有。
用 var 的不足之處?
不足一
來,我們看一段簡短的代碼:
var arr = [ ];
for(var i=0; ?i<10; ?i++){
? ? arr [i] = function(){
????? ? ?alert(i)
????}
}
arr [8]();?//結果:10
????????看代碼,不難猜測代碼的意圖是想給數組a的元素賦值,每一個元素是一個函數,運行后彈出相對應的數字,比如:運行arr[8]();想alert出一個數字8,運行arr[1](); 想alert出一個數字1,依次類推。但是結果并不是我們預想的那樣。運行后實際彈出的是10;不管你運行的是arr[8]還是arr[5],或者是數組內的其他元素,都是alert出一個數字:10。但這并不是我們想要的(不要說你故意這么寫的,就是想彈出10就好了),為什么是10呢(往下讀,有解釋)?至少目前我們可以知道了這是var不足的地方。
?
????????那么let能解決這個問題嗎?ES6說:能啊,不信你試試看!
用let替換var后,我們再看看:
var arr = [ ];
for(let i=0; ?i<10; ?i++){
? ? arr[i] = function(){
????? ? ?alert(i)
????}
}
arr[8](); //結果:8
? ? ? ?對比一下兩段代碼,唯一的不同之處就是循環的時候初始化變量 i 是使用let,而不是用var,運行arr[8]()后確實彈出了數字8;如果運行的是arr[3](),就會彈出數字3;這才是我們的本意啊,總算實現了,感謝上帝,感謝ES6,感謝let關鍵字!
?
????????為什么用let就可以,用var就跑偏了呢?這是因為let聲明的變量僅僅在自己的塊級作用域起作用,出了這個塊級作用域就不起作用。就好比,小明在國內考的“高級程序員”證,去到國外應聘,別人就不承認你的文憑了,小明只能乖乖待在國內持證上崗。而let聲明的變量也一樣,出不了自己的塊級作用域。
????????那么,什么是塊級作用域,怎么才算一個塊級作用域?
????????任何一對花括號(這玩意:{ })中的語句都屬于一個塊,在花括號里面用let定義的所有變量在花括號外都是不可見的,我們稱之為塊級作用域。
?
????????怪不得小明的證件去到美國沒法使用了,人家認為它的證件“不可見“,就是沒這回事,不承認你的證。回到代碼中,for循環含有有{ },也就是含有了塊級作用域,每個變量 i 都只是在自己的作用域起作用,例如:第10次循環中的 i 的值不會影響到到第9次循環。
?
????????如果用var聲明的變量,就不是這種情況了,i 的值會影響到各個塊里面的 i,等循環完后 i 等于10,所有塊的i都變成了10了。這就是為什么第一段代碼運行后會彈出數字10了,這并不是我們想要的。
?
????????就好比小明陸陸續續去了10個國家玩,每到一個國家都給自己弄了一個不同的身份,但是小明被告知以后只能用在第10個國家取得的那個身份,那么之前9個國家認識小明的朋友都會不認識他的,小明當場就懵逼了。
?
不足二
????????用var 聲明變量的時候會出現“變量提升“的現象。
????“?變量提升“是什么鬼?新概念第一次聽?前端君快來解釋一下!
再看一段簡短的代碼:
var a = 1;
(function(){
?? alert(a);
?? var a = 2;
})();//結果:undefined
? ? ? ? 初學者可能認為:代碼一開始已經定義了變量a,值為1,相當于全局變量,代碼運行的時候會先彈出這個全局變量a的值:1;然后再重新給a賦值為2;可偏偏又事與愿違,心好累啊,它會告訴你結果是undefined; undefined就是未定義啊,為什么會是未定義呢?
????????原因就在于我們在代碼塊(函數內)里面還聲明并定義了一個變量a,導致變量提升了,實際的代碼執行順序是這樣的,仔細看完你就知道什么叫變量提升了。
var a = 1;
(function(){
?? var a;
?? alert(a);
?? a = 2;
})();
????????對比一下兩段簡短的代碼:var a = 2; 這句代碼被拆分成兩部分:聲明var a ; 和 定義a = 2;而聲明部分被提升(看到了嗎?提升兩個字出現了)到了代碼塊的前面,運行的時候自己挪到前面了,這就是“變量提升“,結果就是:先執行聲明,接著就執行alert(a);變量a只是聲明還沒定義,就彈出了undefined了。
????????所以,歸根結底就是“變量提升“在作怪。這就是var的又一大不足之處。那么,用let關鍵字在代碼塊就不會被提升了嗎?是的,不提升了。? ? ? ??? ? ?
如果你用let這樣重寫剛剛那段代碼的話:
var a = 1;
(function(){
?? alert(a);
?? let a = 2;
})();?? //?結果:報錯a未定義
????????用let關鍵字來定義a;這樣a在代碼塊內就不會提升了。那為什么又報錯了呢,因為用let聲明的變量,在其塊級作用域內是封閉的,是不會受到外面的全局變量a影響的,并且要先聲明再使用,所以a的值即不是1(因為不受外面的影響),也不是undefined(因為先聲明后使用),更不是2,未聲明定義就使用,只有報錯啦。
?
????????用let關鍵字也算是提醒我們,平時記得先聲明定義再使用的好習慣。
?
????????光是var的不足就講了這么長的篇幅,希望沒把你們悶到,我盡量用一些生活的例子來打比方,如果你能能堅持看到這里很不錯了,還有一點,再堅持一下。
?
????????這么說,let確實能彌補一些var的不足之處。那么使用let的時候還有什么要注意的嗎?有的!
注意1:同一個塊級作用域內,不允許重復聲明同一個變量。
錯誤示范一:
{
? var a =1;
? let a =2; ?//報錯,因為a已經用var聲明過
}
錯誤示范二:
{
? let a =1;
? let a= 2;?//還是報錯,a已經用let聲明過。
}
?
注意2:函數內不能用let重新聲明函數的參數
錯誤示范:
function say(word){
? ? let word = 'hello Jack';? //報錯:用let重新聲明word參數
?? alert(word)
}
say('hello Lili');
say()函數內用let重新聲明了word這個參數,會報錯的,千萬別這么干。
?
?
????????關于ES6新增的let關鍵字,前端君就講述這么多,畢竟涉及到代碼,需要集中精力來看,能堅持到看到這里同學,我要謝謝你們,說明這一節寫得還算易懂!
本節總結
總結:用let聲明變量只在塊級作用域起作用,適合在for循環使用,也不會出現變量提升現象。同一個代碼塊內,不可重復聲明的相同變量,不可重復聲明函數內的參數。
總結
以上是生活随笔為你收集整理的第二节:ES6新增了let关键字,干嘛用的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2014年最受欢迎WEB前端UI框架
- 下一篇: laravel php7.2报错,lar