中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ES6中如何使用let聲明變量以及let loop機制

發布時間:2021-08-19 11:41:59 來源:億速云 閱讀:161 作者:小新 欄目:web開發

這篇文章主要為大家展示了“ES6中如何使用let聲明變量以及let loop機制”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“ES6中如何使用let聲明變量以及let loop機制”這篇文章吧。

相比用var聲明,let聲明的特點

1.let聲明的變量僅在該變量所在的作用域有效

for(let i=0;i<5;i++){} console.log(i); //報錯
for(var i=0;i<5;i++){} console.log(i); //i=5;

2.不存在變量提升

先解釋下變量提升:變量提升就是變量聲明語句都會被提到所在作用域開始處,就是經過變量提升后,代碼的實際執行順序會與你所寫的順序不同。

console.log(i);
var i=2;

因為變量提升,所以上述代碼不會報錯,只會輸出undefined。

但是要注意:變量提升只是提升聲明語句,而不提升賦值語句

所以上述語句經過提升之后,實際的代碼執行順序是

var i;
console.log(i);
i=2;

再來看道經典試題

var name = 'World!'; 
(function () { 
if (typeof name === 'undefined') { 
  var name = 'Jack'; 
  console.log('Goodbye ' + name); 
}else{ 
  console.log('Hello ' + name); 
} 
})();

請問最終console的結果是什么?

如果對變量提升一無所知,會很容易的得出hello world的結果。

我對變量提升略知一二,得出的結果是hello Jack.

但是正確結果是Goodbye Jack. 做錯的原因就是我沒有注意到變量提升僅僅是聲明提升。

3.不可以在同一作用域內重復聲明

function temp(){
   let a;
   let b; 
} //報錯

4.暫時性死區

var tmp="123"; 
if(true){ 
 tmp="abc";
 let tmp;
}

定義(出自ES6標準入門一書):在代碼塊內,使用let變量聲明之前,該變量是不可以用的。這在語法上稱為暫時性死區。

但是如果去掉上述let tmp;這句,代碼是不會錯的,只是這時的tmp即外部的全局變量,但是你如果要聲明一個與外部變量同名的局部變量,那么你就要放在這個同名變量使用之前,否則就會報錯。

說一說(let i=0;i<5;i++)的運行機制

不好意思,我們還得拿閉包來說事。

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

然后,結果i并非我們想象得那樣,按照0,1,2...的順序打印,而都是打印5,在上一篇文章理解js閉包中,我們已經知道如何用閉包解決這個問題。但是呢,這還有一種更簡單的解法,如下

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

對,就是這么簡單,用一個let代替var,就搞定了。但是為什么呢?說實話,閉包我能想得通,但是用let真心想不通為什么可以解決這個問題。問過一些人,但是他們只是很糊弄得說,let是塊級作用域。我覺得他們壓根就沒有搞懂,我覺得這里絕對有蹊蹺,僅僅憑let是塊級作用域并不能解釋的通,一定有其他機制。

我的疑惑:就算let是塊級作用域,可是在函數里,我們沒有定義新的i,所以你訪問i,其實都在訪問父級作用域,對 let i=0;使得i只能在for循環的{}內使用,但是當你調用ai的時候,不管i是多少,它們都應該是訪問的是同一個i,怎么會出現0,1,2,3,4呢?
百度一下,果然不出我所料,阮一峰大神給出的解釋是,對每一次循環,都是產生不同的i,所以5次循環,產生了5個塊級作用域,而不同的塊級作用域間實現i++是通過js引擎記住上一個i值實現的。這樣一來,ai調用時,就會訪問到與自己對應的i,而不是同一個i.

所以,let可以得到閉包的效果是因為let具有塊級作用域,與let loop特殊的機制。

起初,我對這個結果不太相信,因為和直覺不太相符,感覺5次循環,產生5個i,和自己以前的認知不大相同啊。然后我有有了新的發現

第一個發現:

for(let i=0;i<5;i++){
   let i="abc";
   console.log(i);
}

我吃驚的是竟然沒有報錯!說好的let不可以重復聲明呢?這充分證明了let i=0;與let i="abc"不在同一個作用域。

第二個發現:可以通過babel將ES6代碼轉為ES5,看看上述代碼是如何實現的?

ES6中如何使用let聲明變量以及let loop機制

先創建一個loop函數,最終在循環的時候調用loop函數并將i作為參數傳入,這樣便會形成5個不同的副本。這也證明了用let代替閉包,關鍵是形成了5個不同的塊級作用域。

最后,ES6只是一種規范,比如說let的規范,但實現該規范的是JS引擎,如babel對上述代碼的轉換便體現出了babel對let loop的實現。

以上是“ES6中如何使用let聲明變量以及let loop機制”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

壤塘县| 襄城县| 鹤壁市| 铜山县| 百色市| 罗源县| 明光市| 英超| 渭南市| 微山县| 正宁县| 灌阳县| 专栏| 郧西县| 湟中县| 德兴市| 措勤县| 阜平县| 泸溪县| 大埔区| 永嘉县| 西峡县| 安宁市| 江安县| 惠州市| 蓝山县| 义马市| 肥城市| 辽宁省| 健康| 泸西县| 定安县| 麟游县| 万源市| 莱西市| 平山县| 宁南县| 宝应县| 锦屏县| 射阳县| 确山县|