淺談javascript中的閉包
很長(zhǎng)一段時(shí)間不理解閉包,后來(lái)了解了作用域,以及this相關(guān)問(wèn)題才理解了閉包相關(guān)知識(shí)。
閉包(closure),也是面試題常客。簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是函數(shù)嵌套函數(shù)。
函數(shù)作為返回值:
function foo () { var a = 1; return function () { a++; console.log(a); } } var aaa = foo(); aaa(); //2 aaa(); //3
其實(shí)這個(gè)代碼不難理解,aaa是指向foo()返回的一個(gè)新函數(shù),但是在這個(gè)函數(shù)里面引用了a變量,所以當(dāng)執(zhí)行完foo函數(shù)時(shí),變量a還存在內(nèi)存中不釋放。即a分別為2和3。
函數(shù)作為參數(shù):
var a = 10; function foo () { console.log(a); } function aaa(fn) { var a = 100; fn(); } aaa(foo);
按照我以前的理解,當(dāng)執(zhí)行在aaa函數(shù)里面執(zhí)行fn函數(shù),那么如果自身沒有a變量,就去父級(jí)作用域找a變量,此處是100,那結(jié)果是100嗎?
可惜答案不是,在這里結(jié)果是10,王福朋老師的博客講的比較好,他說(shuō)要去創(chuàng)建這個(gè)函數(shù)的作用域取值,而不是“父作用域”。
閉包的使用場(chǎng)景
因?yàn)楸救诉€比較菜鳥,在這里取一個(gè)簡(jiǎn)單例子。當(dāng)點(diǎn)擊li的時(shí)候彈出li在ul中所處的位置即索引值。
html代碼:
<ul> <li>001</li> <li>002</li> <li>003</li> </ul>
js代碼:
示例 1:
請(qǐng)看下面的代碼,運(yùn)行后發(fā)現(xiàn),無(wú)論點(diǎn)擊那個(gè)li,結(jié)果都是3了。
var aLi = document.getElementsByTagName('li'); for (var i = 0; i<aLi.length; i++) { aLi[i].onclick = function() { alert(i); } }
因?yàn)樵谀涿瘮?shù)里面并沒有i變量,所以當(dāng)for結(jié)束后,我們?cè)偃c(diǎn)擊頁(yè)面的li標(biāo)簽,此時(shí)i早就是3了。
示例 2:
aLi[i].onclick = (function(i){ return function(){ alert(i); } })(i);
這次的做法是把函數(shù)當(dāng)返回值,通過(guò)自執(zhí)行函數(shù)的參數(shù),把變量i傳進(jìn)去,然后因?yàn)榉祷睾瘮?shù)要引用這個(gè)i變量,所以當(dāng)for循環(huán)結(jié)束也不會(huì)釋放i變量。即在內(nèi)存中保存了i變量的值?;谶@樣的原理,很容易在低版本ie中造成內(nèi)存泄露。
示例 3:
for (var i = 0; i<aLi.length; i++) { (function(i){ aLi[i].onclick = function(){ alert(i); } })(i); }
這個(gè)原理和上面大同小異。
小米前端閉包面試題:
function repeat (func, times, wait) { } //這個(gè)函數(shù)能返回一個(gè)新函數(shù),比如這樣用 var repeatedFun = repeat(alert, 10, 5000) //調(diào)用這個(gè) repeatedFun ("hellworld") //會(huì)alert十次 helloworld, 每次間隔5秒
我的答案:
function repeat (func, times, wait) { return function(str) { while (times >0) { setTimeout(function(){ func(str); },wait); times--; } } } var repeatedFun = repeat(alert, 10, 100); repeatedFun ("hellworld");
以上所述就是本文的全部?jī)?nèi)容了,希望對(duì)大家學(xué)習(xí)javascript閉包能夠有所幫助。
相關(guān)文章
javascript靜態(tài)頁(yè)面?zhèn)髦档娜N方法分享
這篇文章介紹了javascript靜態(tài)頁(yè)面?zhèn)髦档娜N方法及優(yōu)缺點(diǎn),有需要的朋友可以參考一下2013-11-11點(diǎn)擊標(biāo)簽切換和自動(dòng)切換DIV選項(xiàng)卡
點(diǎn)擊標(biāo)簽切換DIV的效果,在很多地方都有見到過(guò),而且實(shí)現(xiàn)的方法有很多,本例介紹的這個(gè)可以切換和自動(dòng)切換DIV選項(xiàng)卡2014-08-08微信小程序獲取手機(jī)網(wǎng)絡(luò)狀態(tài)的方法【附源碼下載】
這篇文章主要介紹了微信小程序獲取手機(jī)網(wǎng)絡(luò)狀態(tài)的方法,涉及微信小程序wx.getNetworkType函數(shù)檢查網(wǎng)絡(luò)連接狀態(tài)的相關(guān)使用技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2017-12-12微信小程序?qū)崿F(xiàn)tab點(diǎn)擊切換
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)tab點(diǎn)擊切換,不滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07JS中檢測(cè)數(shù)據(jù)類型的幾種方式及優(yōu)缺點(diǎn)小結(jié)
這篇文章主要介紹了JS中檢測(cè)數(shù)據(jù)類型的幾種方式及優(yōu)缺點(diǎn)小結(jié),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12JS通過(guò)Cookie判斷頁(yè)面是否為首次打開
這篇文章主要介紹了JS通過(guò)Cookie判斷頁(yè)面是否為首次打開 的相關(guān)資料,需要的朋友可以參考下2016-02-02