第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

循環(huán)內(nèi)的JavaScript閉包 - 簡(jiǎn)單實(shí)用的例子

循環(huán)內(nèi)的JavaScript閉包 - 簡(jiǎn)單實(shí)用的例子

var funcs = [];for (var i = 0; i < 3; i++) {      // let's create 3 functions  funcs[i] = function() {          // and store them in funcs    console.log("My value: " + i); // each should log its value.  };}for (var j = 0; j < 3; j++) {  funcs[j]();                      // and now let's run each one to see}它輸出這個(gè):我的價(jià)值:3 我的價(jià)值:3 我的價(jià)值:3而我希望它輸出:我的價(jià)值:0 我的價(jià)值:1 我的價(jià)值:2使用事件偵聽器導(dǎo)致運(yùn)行函數(shù)的延遲時(shí),會(huì)出現(xiàn)同樣的問題:var buttons = document.getElementsByTagName("button");for (var i = 0; i < buttons.length; i++) {          // let's create 3 functions  buttons[i].addEventListener("click", function() { // as event listeners    console.log("My value: " + i);                  // each should log its value.  });}<button>0</button><br><button>1</button><br><button>2</button>...或異步代碼,例如使用Promises:// Some async wait functionconst wait = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms));for(var i = 0; i < 3; i++){  wait(i * 100).then(() => console.log(i)); // Log `i` as soon as each promise resolves.}這個(gè)基本問題的解決方案是什么?
查看完整描述

5 回答

?
拉風(fēng)的咖菲貓

TA貢獻(xiàn)1995條經(jīng)驗(yàn) 獲得超2個(gè)贊

好吧,問題是i每個(gè)匿名函數(shù)中的變量都綁定到函數(shù)外部的同一個(gè)變量。


經(jīng)典解決方案:閉包

你想要做的是將每個(gè)函數(shù)中的變量綁定到函數(shù)之外的一個(gè)單獨(dú)的,不變的值:


var funcs = [];


function createfunc(i) {

    return function() { console.log("My value: " + i); };

}


for (var i = 0; i < 3; i++) {

    funcs[i] = createfunc(i);

}


for (var j = 0; j < 3; j++) {

    funcs[j]();                        // and now let's run each one to see

}

由于JavaScript中沒有塊作用域 - 只有函數(shù)作用域 - 通過將函數(shù)創(chuàng)建包裝在新函數(shù)中,可以確?!癷”的值保持不變。


2015解決方案:forEach

隨著Array.prototype.forEach函數(shù)的相對(duì)廣泛的可用性(在2015年),值得注意的是,在涉及主要在一組值上進(jìn)行迭代的那些情況下,.forEach()提供了一種干凈,自然的方式來為每次迭代獲得一個(gè)獨(dú)特的閉包。也就是說,假設(shè)您有某種包含值的數(shù)組(DOM引用,對(duì)象等等),并且設(shè)置了特定于每個(gè)元素的回調(diào)問題,您可以這樣做:


var someArray = [ /* whatever */ ];

// ...

someArray.forEach(function(arrayElement) {

  // ... code code code for this one element

  someAsynchronousFunction(arrayElement, function() {

    arrayElement.doSomething();

  });

});

這個(gè)想法是每次調(diào)用與.forEach循環(huán)一起使用的回調(diào)函數(shù)都是它自己的閉包。傳遞給該處理程序的參數(shù)是特定于該迭代的特定步驟的數(shù)組元素。如果它在異步回調(diào)中使用,它將不會(huì)與在迭代的其他步驟中建立的任何其他回調(diào)沖突。


如果你碰巧在jQuery中工作,該$.each()函數(shù)會(huì)為你提供類似的功能。


ES6解決方案: let

ECMAScript 6(ES6)引入了新的let和const關(guān)鍵字,其范圍與var基于變量的不同。例如,在具有l(wèi)et基于索引的循環(huán)中,循環(huán)中的每次迭代都將具有一個(gè)新值,i其中每個(gè)值都在循環(huán)中作用域,因此您的代碼將按預(yù)期工作。有很多資源,但我建議將2ality的區(qū)塊范圍發(fā)布作為一個(gè)很好的信息來源。


for (let i = 0; i < 3; i++) {

    funcs[i] = function() {

        console.log("My value: " + i);

    };

}

但要注意,IE9-IE11和Edge在Edge 14支持之前l(fā)et卻出現(xiàn)了上述錯(cuò)誤(它們i每次都沒有創(chuàng)建新的,所以上面的所有函數(shù)都會(huì)像我們使用的那樣記錄3 var)。Edge 14最終做對(duì)了。


查看完整回答
反對(duì) 回復(fù) 2019-05-20
?
胡說叔叔

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超8個(gè)贊

嘗試:

var funcs = [];for (var i = 0; i < 3; i++) {
    funcs[i] = (function(index) {
        return function() {
            console.log("My value: " + index);
        };
    }(i));}for (var j = 0; j < 3; j++) {
    funcs[j]();}


查看完整回答
反對(duì) 回復(fù) 2019-05-20
?
莫回?zé)o

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個(gè)贊

使用立即調(diào)用的函數(shù)表達(dá)式,這是封裝索引變量的最簡(jiǎn)單,最易讀的方法:

for (var i = 0; i < 3; i++) {

    (function(index) {
        console.log('iterator: ' + index);
        //now you can also loop an ajax call here 
        //without losing track of the iterator value: $.ajax({});
    })(i);}

這會(huì)將迭代器發(fā)送i到我們定義為的匿名函數(shù)中index。這將創(chuàng)建一個(gè)閉包,i保存變量以供以后在IIFE中的任何異步功能中使用。


查看完整回答
反對(duì) 回復(fù) 2019-05-20
?
滄海一幻覺

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超5個(gè)贊

另一種說法是,i函數(shù)中的函數(shù)在執(zhí)行函數(shù)時(shí)受到約束,而不是創(chuàng)建函數(shù)的時(shí)間。

創(chuàng)建閉包時(shí),i是對(duì)外部作用域中定義的變量的引用,而不是創(chuàng)建閉包時(shí)的副本。它將在執(zhí)行時(shí)進(jìn)行評(píng)估。

大多數(shù)其他答案提供了通過創(chuàng)建另一個(gè)不會(huì)為您更改值的變量來解決的方法。

我想我會(huì)添加一個(gè)清晰的解釋。對(duì)于一個(gè)解決方案,就個(gè)人而言,我會(huì)選擇Harto,因?yàn)閺倪@里的答案來看,這是最不言自明的方式。發(fā)布的任何代碼都可以使用,但我選擇封閉工廠而不必寫一堆注釋來解釋為什么我要聲明一個(gè)新變量(Freddy和1800's)或者有奇怪的嵌入式閉包語法(apphacker)。


查看完整回答
反對(duì) 回復(fù) 2019-05-20
  • 5 回答
  • 0 關(guān)注
  • 1174 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)