理解javascript閉包
什么是javascript閉包?
javascript允許使用內(nèi)部函數(shù),內(nèi)部函數(shù)可以訪問它們所在的外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù)。當(dāng)其中一個這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時,就會形成閉包。
簡單的javascript閉包例子:
<script>
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
</script>
在這段代碼中,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動清除。
為什么會這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。
這段代碼中另一個值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個全局變量,而不是局部變量。其次,nAdd的值是一個匿名函數(shù)(anonymous function),而這個匿名函數(shù)本身也是一個閉包,所以nAdd相當(dāng)于是一個setter,可以在函數(shù)外部對函數(shù)內(nèi)部的局部變量進(jìn)行操作。
閉包的應(yīng)用:
var singleton = function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}
return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
}();
這個單件通過閉包來實(shí)現(xiàn)。通過閉包完成了私有的成員和方法的封裝。匿名主函數(shù)返回一個對象。對象包含了兩個方法,方法1可以方法私有變量,方法2訪問內(nèi)部私有函數(shù)。需要注意的地方是匿名主函數(shù)結(jié)束的地方的'()',如果沒有這個'()'就不能產(chǎn)生單件。因?yàn)槟涿瘮?shù)只能返回了唯一的對象,而且不能被其他地方調(diào)用。這個就是利用閉包產(chǎn)生單件的方法。
閉包的優(yōu)勢:
(1)不增加額外的全局變量,
(2)執(zhí)行過程中所有變量都是在匿名函數(shù)內(nèi)部。
閉包的缺點(diǎn):
(1)由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
(2)閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
本文就為大家介紹這里,如果大家對javascript閉包還是不夠了解,請閱讀相關(guān)文章進(jìn)行補(bǔ)充學(xué)習(xí),謝謝大家的閱讀。
相關(guān)文章
JavaScript中16進(jìn)制顏色與rgb顏色互相轉(zhuǎn)換的示例代碼
這篇文章主要介紹了JavaScript中16進(jìn)制顏色與rgb顏色互相轉(zhuǎn)換的示例代碼,通過示例代碼介紹了JS 顏色16進(jìn)制、rgba相互轉(zhuǎn)換問題,感興趣的朋友一起看看吧2024-01-01
js生成1到100的隨機(jī)數(shù)最簡單的實(shí)現(xiàn)方法
在本篇文章里小編給大家整理了關(guān)于js生成1到100的隨機(jī)數(shù)最簡單的實(shí)現(xiàn)方法,有需要的朋友們可以學(xué)習(xí)下。2020-02-02
詳解JavaScript如何實(shí)現(xiàn)異步并發(fā)任務(wù)控制器
實(shí)現(xiàn)一個控制并發(fā)數(shù)的任務(wù)隊(duì)列?、實(shí)現(xiàn)一個異步并發(fā)任務(wù)控制器,這已經(jīng)是非常經(jīng)典的手寫題目了,因?yàn)槠渲猩婕?異步?和?并發(fā)?的內(nèi)容,所以本文就來講講到底如何實(shí)現(xiàn)呢2023-05-05
JS/HTML5游戲常用算法之碰撞檢測 包圍盒檢測算法詳解【凹多邊形的分離軸檢測算法】
這篇文章主要介紹了JS/HTML5游戲常用算法之碰撞檢測 包圍盒檢測算法,結(jié)合實(shí)例形式詳細(xì)分析了javascript針對凹多邊形的分離軸檢測算法相關(guān)概念、原理、實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2018-12-12

