淺談javascript中的閉包
很長一段時(shí)間不理解閉包,后來了解了作用域,以及this相關(guān)問題才理解了閉包相關(guān)知識(shí)。
閉包(closure),也是面試題???。簡單點(diǎn)來說就是函數(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,王福朋老師的博客講的比較好,他說要去創(chuàng)建這個(gè)函數(shù)的作用域取值,而不是“父作用域”。
閉包的使用場景
因?yàn)楸救诉€比較菜鳥,在這里取一個(gè)簡單例子。當(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),無論點(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)擊頁面的li標(biāo)簽,此時(shí)i早就是3了。
示例 2:
aLi[i].onclick = (function(i){
return function(){
alert(i);
}
})(i);
這次的做法是把函數(shù)當(dāng)返回值,通過自執(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");
以上所述就是本文的全部內(nèi)容了,希望對(duì)大家學(xué)習(xí)javascript閉包能夠有所幫助。
相關(guān)文章
微信小程序使用uni-app開發(fā)小程序及部分功能實(shí)現(xiàn)詳解
uni-app是一個(gè)使用Vue.js 開發(fā)所有前端應(yīng)用的框架,下面這篇文章主要給大家介紹了關(guān)于微信小程序使用uni-app開發(fā)小程序及部分功能實(shí)現(xiàn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
JS中‘hello’與new String(‘hello’)引出的問題詳解
這篇文章主要給大家介紹了關(guān)于JS中'hello'與new String('hello')引出的問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
webpack打包后index.html引用文件地址問題小結(jié)
在前端開發(fā)中,src 屬性指定的相對(duì)路徑是相對(duì)于當(dāng)前 HTML 文件的路徑,而不是相對(duì)于網(wǎng)站的根目錄,這篇文章主要介紹了webpack打包后index.html引用文件地址問題,需要的朋友可以參考下2024-05-05
JavaScript單線程和任務(wù)隊(duì)列原理解析
這篇文章主要介紹了JavaScript單線程和任務(wù)隊(duì)列原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
JS一維數(shù)組轉(zhuǎn)多維數(shù)組樹的方法
這篇文章主要介紹了JS一維數(shù)組轉(zhuǎn)多維數(shù)組樹的方法,文章通過代碼示例給大家講解的非常詳細(xì),?對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-06-06
通過JS 獲取Mouse Position(鼠標(biāo)坐標(biāo))的代碼
最近我發(fā)現(xiàn)在webpage中獲取空間的絕對(duì)坐標(biāo)時(shí),如果有滾動(dòng)條就會(huì)有錯(cuò),后來用無名發(fā)現(xiàn)的方法得以解決。2009-09-09

