js 中的閉包

什么是閉包?

閉包的定義其實(shí)很簡(jiǎn)單:函數(shù) A 內(nèi)部有一個(gè)函數(shù) B,函數(shù) B 可以訪問(wèn)到函數(shù) A 中的變量,那么函數(shù) B 就是閉包。舉例:

const a = function() {
    let n = 1
    return function() {
        console.log(n)
        n++
    }
}
const b = a()
b() // result: 1
b() // result: 2

在 JS 中,閉包存在的意義就是讓我們可以間接訪問(wèn)函數(shù)內(nèi)部的變量。

循環(huán)中使用閉包解決 var 定義函數(shù)的問(wèn)題

for (var i = 1; i <= 5; i++) {
    setTimeout(function timer() {
        console.log(i)
    }, i*1000)
}
//result;全是 6

因?yàn)?setTimeout 是個(gè)異步函數(shù),所以會(huì)先把循環(huán)全部執(zhí)行完畢,這時(shí)候 i就是 6 了,所以會(huì)輸出一堆 6。

解決辦法(三種)

一、使用閉包

for (var i = 1; i <= 5; i++) {
    ;(function timer(j) {
        setTimeout(function() {
            console.log(j)
        }, j*1000)
    })(i)
}
// result: 1 2 3 4 5

在上面的代碼中,我們使用立即執(zhí)行函數(shù)將 i 傳入函數(shù)內(nèi)部,這個(gè)時(shí)候值就被固定在了參數(shù) j 上面不會(huì)改變,當(dāng)下次執(zhí)行 timer 這個(gè)閉包的時(shí)候,就可以使用外部函數(shù)的變量 j,從而達(dá)到目的。(其實(shí)相當(dāng)于創(chuàng)建了 5 個(gè)函數(shù)作用域, timer 執(zhí)行的時(shí)候就在自己的作用域里去訪問(wèn) j 的值,而不是統(tǒng)一訪問(wèn) i)

第二種就是使用 setTimeout 的第三個(gè)參數(shù),這個(gè)參數(shù)會(huì)被當(dāng)成 timer 函數(shù)的參數(shù)傳入。

for (var i = 1; i <= 5; i++) {
  setTimeout(
    function timer(j) {
      console.log(j)
    },
    i * 1000,
    i
  )
}

第三種就是使用 let 定義 i 了來(lái)解決問(wèn)題了,這個(gè)也是 最為推薦 的方式

for (let i = 1; i <= 5; i++) {
  setTimeout(function timer() {
    console.log(i)
  }, i * 1000)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容