關(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)文章
微信小程序 實(shí)現(xiàn)拖拽事件監(jiān)聽(tīng)實(shí)例詳解
這篇文章主要介紹了微信小程序 實(shí)現(xiàn)拖拽事件監(jiān)聽(tīng)實(shí)例詳解的相關(guān)資料,在開(kāi)發(fā)不少應(yīng)用或者軟件都要用到這樣的方法,這里就對(duì)微信小程序?qū)崿F(xiàn)該功能進(jìn)行介紹,需要的朋友可以參考下2016-11-11TypeScript?泛型推斷實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了TypeScript?泛型推斷實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08微信小程序本作用域下調(diào)用全局JS詳解及實(shí)例
這篇文章主要介紹了微信小程序本作用域下調(diào)用全局JS詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02JS精髓原型鏈繼承及構(gòu)造函數(shù)繼承問(wèn)題糾正
這篇文章主要為大家介紹了JS精髓原型鏈繼承及構(gòu)造函數(shù)繼承問(wèn)題糾正,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06TS?項(xiàng)目中高效處理接口返回?cái)?shù)據(jù)方法詳解
這篇文章主要為大家介紹了TS?項(xiàng)目中如何高效的處理接口返回的數(shù)據(jù)的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Typescript?封裝?Axios攔截器方法實(shí)例
這篇文章主要為大家介紹了Typescript?封裝?Axios攔截器方法實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09JavaScript實(shí)現(xiàn)放大鏡詳細(xì)
這篇文章主要介紹了js實(shí)現(xiàn)放大鏡,借助寬高等比例放大的兩張圖片,結(jié)合js中鼠標(biāo)偏移量、元素偏移量、元素自身寬高等屬性完成;左側(cè)遮罩移動(dòng)Xpx,右側(cè)大圖移動(dòng)X*倍數(shù)px,具體內(nèi)容請(qǐng)需要的小伙伴出差下面文章內(nèi)容2021-12-12總結(jié)JavaScript中BigIn函數(shù)常見(jiàn)的屬性
本文基于JavaScript基礎(chǔ),介紹了 BigInt 函數(shù),常見(jiàn)的屬性,通過(guò) BigInt 函數(shù)進(jìn)行數(shù)字運(yùn)算符的比較。布爾運(yùn)算等等,通過(guò)按案例的分析進(jìn)行詳細(xì)的講解,需要的朋友可以參考一下2021-10-10微信小程序 LOL 英雄介紹開(kāi)發(fā)實(shí)例
這篇文章主要介紹了微信小程序 LOL 英雄介紹開(kāi)發(fā)的相關(guān)資料,需要的朋友可以參考下2016-09-09