解析JavaScript迴圈和範圍之間的關係(附代碼)

來源:互聯網
上載者:User
我們在工作中經常會用到JavaScript,他與我們的工作有密切的關係。但是JavaScript有一個特點,也許會讓開發人員頭痛, 是其迴圈和範圍相關的,那接下裡就說說他們之間的關係。

舉個例子:

const operations = []for (var i = 0; i < 5; i++) {  operations.push(() => {    console.log(i)  })}for (const operation of operations) {  operation()}

它基本是迴圈了5次,將一個函數添加到operations數組裡面。這個函數可列印出迴圈變數索引值i.
運行這些函數後期望的結果應該是:
0 1 2 3 4

但實際發生的是這樣的:

5 5 5 5 5

為什麼會有這種情況? 因為使用的是var.由於提升了var變數, 上面的代碼等同於

var i;const operations = []for (i = 0; i < 5; i++) {  operations.push(() => {    console.log(i)  })}for (const operation of operations) {  operation()}

因此,在for-of迴圈中, i 依然是可見的, 它等於5,並且每次在函數中涉及到i ,都將使用這個值。
那麼我們應該如何做讓其變成我們想的這樣呢?
最簡單的方案是用 let 聲明. 在ES2015中介紹到, 它們有很大的協助,能避免關於使用var聲明的一些奇怪問題。
簡單的在迴圈變數時將var 變成 let ,能夠很好的運行:

const operations = []for (let i = 0; i < 5; i++) {  operations.push(() => {    console.log(i)  })}for (const operation of operations) {  operation()}

這是輸出結果:

0 1 2 3 4

這是怎麼實現的呢?這是因為每次迴圈重複的時候,都將重新創造 i ,同時每個函數添加operations數組時,能擷取它本身的i。
記住你不能使用 const在這種情況下, 因為這會導致for在第二次迴圈時, 嘗試賦新值報錯。
另外一個非常普遍的解決這個問題是使用pre-ES6代碼, 同時它被稱作即時調用函數運算式 (IIFE).
在這種情況下,你可以封裝整個函數,並將i 綁定在它上面。自這種方式,你正在創造一個能立即執行的函數,你從其返回的一個新的函數。因此我們可以稍後執行它。

const operations = []for (var i = 0; i < 5; i++) {  operations.push(((j) => {    return () => console.log(j)  })(i))}for (const operation of operations) {  operation()}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.