鍍金池/ 問答/HTML/ JS作用域和閉包

JS作用域和閉包

圖片描述

這里的 i 是指向全局的 i 所有全部都是10,這個(gè)沒問題

然后我把i寫在函數(shù)里面,把他變成局部
圖片描述

然后點(diǎn)擊BUTTON 輸出全部都是 4 也就是btn.length 這個(gè)好理解,綁定事件回調(diào)函數(shù)指向都是局部變量的i,問題來了,事件綁定是異步的,f1()調(diào)用完后,f1函數(shù)的局部作用域要釋放。點(diǎn)擊BUTTON為什么還是4,請問這里形成閉包了嗎?有沒有大神解釋下

然后

圖片描述

這里又是怎么理解?求大神分析

回答
編輯回答
雨萌萌

你4個(gè)button的那個(gè)js,你沒有把for循環(huán)中的i當(dāng)作參數(shù)傳入進(jìn)事件中,你調(diào)用了最外面的f1(),也只是執(zhí)行這個(gè)函數(shù)里面可執(zhí)行的程序段,也就是說你for循環(huán)確實(shí)在執(zhí)行了,但是循環(huán)里面的監(jiān)聽事件你不會(huì)去觸發(fā),那么無論你怎么監(jiān)聽,你的i最后輸出只會(huì)是4。給你看一個(gè)log大法你應(yīng)該就能明白了圖片描述

而你最后一個(gè)程序那是把i當(dāng)參數(shù)傳進(jìn)去了,所以你會(huì)輸出每個(gè)i值,其實(shí)現(xiàn)在你完全可以用es6的語法直接一鍵搞定這個(gè)問題,把var改成let就行
圖片描述

2018年4月26日 19:09
編輯回答
大濕胸

形成閉包了。

f1的局部作用域沒有釋放,因?yàn)樵?code>click的回調(diào)函數(shù)中保持了對i變量的引用,因此i不會(huì)被垃圾回收算法回收

==================

對于題主補(bǔ)充的圖片:

這里是使用function創(chuàng)造了一個(gè)局部作用域,并把i的值傳進(jìn)去,對于每個(gè)click回調(diào)函數(shù),他訪問的i都來源于不同的IIFE,因此值是不同的。

2018年5月13日 14:52
編輯回答
有點(diǎn)壞

是的,形成閉包了?;卣{(diào)函數(shù)在執(zhí)行完之后不會(huì)被回收,因?yàn)樗鼘⒌却磥肀徽{(diào)用。而此回調(diào)函數(shù)又引用了f1作用域里的變量,所以f1的整個(gè)作用域都未被回收,形成閉包。

2018年2月13日 22:51
編輯回答
避風(fēng)港

第一段代碼執(zhí)行的結(jié)果是這樣的:

a[0] = function(){console.log(i)};//這里函數(shù)體里的i還沒有被執(zhí)行 下同
a[1] = function(){console.log(i)};
a[2] = function(){console.log(i)};
a[3] = function(){console.log(i)};
a[4] = function(){console.log(i)};
a[5] = function(){console.log(i)};
a[6] = function(){console.log(i)};
a[7] = function(){console.log(i)};
a[8] = function(){console.log(i)};
a[9] = function(){console.log(i)};

當(dāng)執(zhí)行完for循環(huán)后 i的值就變成10了 這樣再調(diào)用任意的a[i] 都是輸出10

第二段和第一段沒區(qū)別啊 就類似于把第一段寫在一個(gè)函數(shù)內(nèi) 那么函數(shù)一執(zhí)行 不就和第一段一樣了么?

btn[0] = function(){ alert(i) };
btn[1] = function(){ alert(i) };
btn[2] = function(){ alert(i) };
btn[3] = function(){ alert(i) };

for循環(huán)結(jié)束后i的值變?yōu)?,任意點(diǎn)擊按鈕,都是輸出4。

第三段的話是典型的閉包 引用上面"dablwow80"的話 function創(chuàng)造了一個(gè)局部作用域,每個(gè)i都是獨(dú)立的~

2018年6月12日 12:35
編輯回答
涼汐

第一段,作用域,全局/局部/塊級
第二段,i作為局部變量,并不會(huì)被GC,for循環(huán)仍在引用
第三段,函數(shù)作為參數(shù)傳遞,閉包

2017年9月26日 19:10
編輯回答
雨萌萌

第二段里面console.log(i)還在引用i,所以是不會(huì)釋放i的。
第三段形成了閉包,閉包內(nèi)部查詢i的時(shí)候在參數(shù)中查找到i了,就不會(huì)再向外去查找了。

2017年2月8日 15:06