關(guān)于Javascript閉包與應(yīng)用的詳解
前言
Javascript閉包在學(xué)習(xí)過(guò)程中一般較難理解,本文從什么是閉包,常見(jiàn)閉包示例,閉包作用,閉包應(yīng)用及閉包問(wèn)題等方面來(lái)介紹閉包,希望能給大家?guī)?lái)更深層次的認(rèn)識(shí),有不恰當(dāng)之處請(qǐng)指出,謝謝。
一、什么是閉包?
閉包是指一個(gè)嵌套的內(nèi)部(子)函數(shù)引用了父函數(shù)作用域中數(shù)據(jù)的函數(shù),這就產(chǎn)生了閉包。
關(guān)鍵理解:
1. 產(chǎn)生閉包必須要有嵌套函數(shù)
2. 閉包是函數(shù),并是嵌套的內(nèi)部函數(shù)
3. 閉包內(nèi)部函數(shù)必須要引用父函數(shù)作用域中數(shù)據(jù)
如果不滿足以上條件,則不能產(chǎn)生閉包,接下來(lái)示例說(shuō)明。
1.1閉包滿足條件代碼
<script>
function person(){
var name='marshal';
function student(){ //聲明子函數(shù)
console.log(name);//引用父函數(shù)作用域的變量name
}
}
person();//函數(shù)執(zhí)行,產(chǎn)生閉包
</script>

1.2閉包產(chǎn)生時(shí)機(jī)
<script>
function person(){
var name='marshal';//js執(zhí)行此行時(shí),產(chǎn)生閉包
function student(){ //聲明子函數(shù)
console.log(name);//引用父函數(shù)作用域的變量name
}
student();//內(nèi)部函數(shù)在外部函數(shù)調(diào)用
}
person();//函數(shù)執(zhí)行,雖滿足閉包條件,但未產(chǎn)生閉包
</script>

閉包產(chǎn)生時(shí)機(jī):嵌套子函數(shù)代碼塊有引用父函數(shù)作用域的數(shù)據(jù),并該嵌套子函數(shù)要執(zhí)行前,創(chuàng)建上下文時(shí)產(chǎn)生閉包?;蛘吆?jiǎn)單說(shuō)該該嵌套子函數(shù)在外部被執(zhí)行時(shí),此刻產(chǎn)生了閉包。
<script>
function person(){
var name='marshal';
function student(){
console.log(name); //該方法代碼內(nèi)為閉包代碼
}
return student;
}
var p=person();//因創(chuàng)建子函數(shù)對(duì)像,此時(shí)產(chǎn)生第一次閉包,并將子函數(shù)student返回給p,由于p沒(méi)有消失,子函數(shù)引用的變量name,一直在內(nèi)存在存儲(chǔ),直到將p=null,進(jìn)行回收
p();//執(zhí)行子函數(shù)的閉包代碼塊,輸出"marhsal"
p();//第二次執(zhí)行子函數(shù)的閉包代碼塊,輸出"marhsal"
person();//第二次創(chuàng)建子函數(shù)調(diào)對(duì)象,此時(shí)產(chǎn)生第二次閉包,但不執(zhí)行子函數(shù)student代碼塊
</script>
二、常見(jiàn)閉包示例
2.1 子函數(shù)做為實(shí)參傳遞
<script>
function setTimeoutTest(message,time){
setTimeout(function(){
alert(message);//嵌套子函數(shù)引用父函數(shù)變量message,產(chǎn)生閉包
},time);
}
setTimeoutTest('提示信息',1000);
</script>
2.2 計(jì)數(shù)器使用(函數(shù)返回)
<script>
function count(){
var i=1;
function add(){
i++;
console.log(i);
}
return add;
}
var c=count();//生產(chǎn)閉包
c();//2
c();//3
c();//4
</script>
三、閉包作用
3.1 閉包作用
1)子函數(shù)引用父函數(shù)的變量或函數(shù),生命周期延長(zhǎng)
2)其變量或函數(shù)一直存在,外部可以訪問(wèn)函數(shù)內(nèi)部的值
<script>
function count(){
var i=1;
function add(){
i++;
console.log(i);
}
return add;
}
var c=count();
c();//2
c();//3 i的生命周期延長(zhǎng)
</script>
四、閉包應(yīng)用
4.1 自定義封裝js代碼
外部js代碼 out.js 實(shí)現(xiàn)自加與自減
(function count(){
var i=1;
function add(){
i++;
console.log(i);
}
function subtract(){
i--
console.log(i);
}
window.count={
add:add,
subtract:subtract
}
})();
引用 out.js代碼 <script src=out.js></script> <script> count.add(); //2 count.subtract();//1 count.subtract();//0 </script>
五、閉包問(wèn)題
5.1 閉包與this
<script>
var name="marshal"; //創(chuàng)建全局變量
var person={
name:"leo",
getName:function(){ //返回匿名函數(shù)
return function(){ //返回this.name
return this.name; //返回字符串
}
}
};
alert(person.getName()()); //輸出marshal,內(nèi)部函數(shù)不可能直接訪問(wèn)外部函數(shù)this
</script>
解決方法
<script>
var name="marshal";
var person={
name:"leo",
getName:function(){
var that=this;//把this保存到閉包可以訪問(wèn)的另一個(gè)變量中
return function(){
return that.name;
}
}
};
alert(person.getName()());//that 指向person,而不是window
</script>
5.2 內(nèi)存泄露
在使用閉包時(shí),因變量一直存在,需要解除對(duì)象的引用,將對(duì)象設(shè)置為null, 從而確保其內(nèi)存在適當(dāng)時(shí)候可以被回收。
到此這篇關(guān)于關(guān)于Javascript閉包與應(yīng)用的詳解的文章就介紹到這了,更多相關(guān)js閉包與應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Three.js實(shí)現(xiàn)雪糕地球的使用示例詳解
這篇文章主要為大家介紹了Three.js實(shí)現(xiàn)雪糕地球的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
JavaScript中七種流行的開(kāi)源機(jī)器學(xué)習(xí)框架
今天小編就為大家分享一篇關(guān)于JavaScript中五種流行的開(kāi)源機(jī)器學(xué)習(xí)框架,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
詳解微信小程序Page中data數(shù)據(jù)操作和函數(shù)調(diào)用
這篇文章主要介紹了詳解微信小程序Page中data數(shù)據(jù)操作和函數(shù)調(diào)用的相關(guān)資料,希望通過(guò)本文能幫助到大家掌握這方法,需要的朋友可以參考下2017-09-09
微信小程序聯(lián)網(wǎng)請(qǐng)求的輪播圖
這篇文章主要介紹了微信小程序聯(lián)網(wǎng)請(qǐng)求的輪播圖的相關(guān)資料,需要的朋友可以參考下2017-07-07
微信小程序 flex實(shí)現(xiàn)導(dǎo)航實(shí)例詳解
這篇文章主要介紹了微信小程序 flex實(shí)現(xiàn)導(dǎo)航實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04

