摘要:一般來(lái)講,函數(shù)執(zhí)行完畢后,局部活動(dòng)對(duì)象就會(huì)被銷(xiāo)毀,內(nèi)存中僅保存全局作用域,但是閉包的情況有所不同理解閉包的前提先理解另外兩個(gè)內(nèi)容作用域鏈垃圾回收作用域鏈當(dāng)代碼在執(zhí)行過(guò)程中,會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈。
閉包是javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包來(lái)實(shí)現(xiàn)。個(gè)人的理解是:函數(shù)中嵌套函數(shù)。
閉包的定義及其優(yōu)缺點(diǎn)閉包是指有權(quán)訪(fǎng)問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見(jiàn)方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。
閉包的缺點(diǎn)是常駐內(nèi)存,會(huì)增大內(nèi)存的使用量,使用不當(dāng)會(huì)造成內(nèi)存泄漏。
應(yīng)用閉包主要是為了:設(shè)計(jì)私有變量和方法。
一般來(lái)講,函數(shù)執(zhí)行完畢后,局部活動(dòng)對(duì)象就會(huì)被銷(xiāo)毀,內(nèi)存中僅保存全局作用域,但是閉包的情況有所不同!
理解閉包的前提先理解另外兩個(gè)內(nèi)容:作用域鏈、垃圾回收作用域鏈:當(dāng)代碼在執(zhí)行過(guò)程中,會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈。作用域鏈的用途,是保證對(duì)執(zhí)行環(huán)境有權(quán)訪(fǎng)問(wèn)的所有變量和函數(shù)的有序訪(fǎng)問(wèn)。
請(qǐng)看下面的一段代碼:
//全局環(huán)境中有一個(gè)變量color和一個(gè)函數(shù)changeColor() var color = "blue"; //changeColor()的局部環(huán)境中有一個(gè)anotherColor變量和swapColors()函數(shù) function changeColor() { var anotherColor = "red"; //swapColors()環(huán)境中只有一個(gè)tempColor function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; } swapColors(); } changeColor();
全局環(huán)境只能訪(fǎng)問(wèn)到變量color
changeColor()局部環(huán)境也可以訪(fǎng)問(wèn)color
swapColors()可以訪(fǎng)問(wèn)其他兩個(gè)環(huán)境的所有變量,但是那兩個(gè)變量都無(wú)權(quán)訪(fǎng)問(wèn)tempColor
總結(jié):內(nèi)部環(huán)境可以通過(guò)作用域鏈訪(fǎng)問(wèn)所有的外部環(huán)境,但外部環(huán)境不能訪(fǎng)問(wèn)內(nèi)部環(huán)境中的任何變量和函數(shù)。每個(gè)環(huán)境都可以向上搜索作用域鏈,但任何環(huán)境都不能向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。
垃圾回收原理
(1)javascript中如果一個(gè)對(duì)象不再被引用,那么這個(gè)對(duì)象就會(huì)被回收。
(2)如果兩個(gè)對(duì)象互相引用,而不再被第3者引用,那么這兩個(gè)互相引用的對(duì)象也會(huì)被回收。
嵌套函數(shù)的閉包
var f = function () { var a = 9999; function f1() { alert(a); } f1(); }; f();
函數(shù)嵌套時(shí)候,在f執(zhí)行完成之后,變量a還要被f1這個(gè)內(nèi)部嵌套的函數(shù)繼續(xù)使用,因此a不會(huì)被釋放。js解析器發(fā)現(xiàn)函數(shù)中嵌套了函數(shù)時(shí),就會(huì)把函數(shù)中的變量和子函數(shù)的變量一起保存,構(gòu)成了一個(gè)“閉包”。這些變量不會(huì)被內(nèi)存回收器回收,只有當(dāng)內(nèi)部嵌套的函數(shù)不在執(zhí)行后,才會(huì)被回收。
閉包的特性和使用閉包的好處閉包有三個(gè)特性:
1.函數(shù)嵌套函數(shù)
2.函數(shù)內(nèi)部可以引用外部的參數(shù)和變量
3.參數(shù)和變量不會(huì)被垃圾回收機(jī)制回收
使用閉包的好處:
1.希望一個(gè)變量長(zhǎng)期駐扎內(nèi)存
2.避免全局變量污染
3.私有成員變量的存在
屬性
var person = function () { var name = "kimi"; this.getName = function () { return name; }; }; var p = new person(); alert(p.getName());
name屬性通過(guò)getName方法獲取到。
在循環(huán)中直接找到對(duì)應(yīng)元素的索引
執(zhí)行以上代碼發(fā)現(xiàn)點(diǎn)擊任何一個(gè)返回的都是4,這是因?yàn)橘x值的時(shí)候,傳的i是對(duì)內(nèi)存地址的引用,循環(huán)結(jié)束,i指向的就是4.
使用閉包改寫(xiě)上面的代碼
閉包
每一次循環(huán)的時(shí)候,都把當(dāng)前的i通過(guò)立即執(zhí)行函數(shù)賦值。
變量的累加全局變量的累加
局部變量的累加
上述代碼沒(méi)有實(shí)現(xiàn)累加,改寫(xiě)代碼如下:
模塊化代碼,減少全局變量的污染 this對(duì)象在閉包中使用this對(duì)象可能導(dǎo)致一些問(wèn)題
代碼先創(chuàng)建了一個(gè)全局變量name,又創(chuàng)建了一個(gè)包含name屬性的對(duì)象。這個(gè)對(duì)象還包含一個(gè)getNameFunc()方法,返回一個(gè)匿名函數(shù),匿名函數(shù)又返回一個(gè)this.name。調(diào)用object.getNameFunc()()返回一個(gè)字符串。內(nèi)部函數(shù)搜索的時(shí)候只搜索到活動(dòng)對(duì)象。
在定義匿名函數(shù)前,把this對(duì)象賦值給that變量,閉包也可以訪(fǎng)問(wèn)這個(gè)變量。即使函數(shù)返回,仍然引用著object
學(xué)習(xí)了閉包也不知道到底哪里用到,到底有什么用?;卮穑?其實(shí)你寫(xiě)的每一個(gè)js函數(shù)都是閉包,一個(gè)js函數(shù)的頂層作用域就是window對(duì)象,js的執(zhí)行環(huán)境本身就是一個(gè)scope(瀏覽器的window/node的global),我們通常稱(chēng)之為全局作用域。每個(gè)函數(shù),不論多深,都可以認(rèn)為是全局scope的子作用域,可以理解為閉包。)
本篇文章是自己學(xué)習(xí)過(guò)程中的總結(jié),如有錯(cuò)誤歡迎指正。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82442.html
摘要:當(dāng)初看這個(gè)解釋有點(diǎn)懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿(mǎn)足于只干前端的活,開(kāi)始用起了。里的閉包最近在學(xué)習(xí)語(yǔ)言,讓我們來(lái)看一下語(yǔ)言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開(kāi)始接觸編程是從js開(kāi)始的,當(dāng)時(shí)網(wǎng)上很多人說(shuō)閉包是難點(diǎn),各種地方對(duì)閉包的解釋也是千奇百怪。如今開(kāi)始接觸js以外的各種編程語(yǔ)言,發(fā)現(xiàn)不光是js,php、...
摘要:當(dāng)初看這個(gè)解釋有點(diǎn)懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿(mǎn)足于只干前端的活,開(kāi)始用起了。里的閉包最近在學(xué)習(xí)語(yǔ)言,讓我們來(lái)看一下語(yǔ)言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開(kāi)始接觸編程是從js開(kāi)始的,當(dāng)時(shí)網(wǎng)上很多人說(shuō)閉包是難點(diǎn),各種地方對(duì)閉包的解釋也是千奇百怪。如今開(kāi)始接觸js以外的各種編程語(yǔ)言,發(fā)現(xiàn)不光是js,php、...
摘要:如何在初學(xué)就理解閉包你需要接著讀下去。這樣定義閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合。小結(jié)閉包在中隨處可見(jiàn)。閉包是中的精華部分,理解它需要具備一定的作用域執(zhí)行棧的知識(shí)。 這是本系列的第 4 篇文章。 作為 JS 初學(xué)者,第一次接觸閉包的概念是因?yàn)閷?xiě)出了類(lèi)似下面的代碼: for (var i = 0; i < helpText.length; i++) { var item = he...
摘要:閉包引起的內(nèi)存泄漏總結(jié)從理論的角度將由于作用域鏈的特性中所有函數(shù)都是閉包但是從應(yīng)用的角度來(lái)說(shuō)只有當(dāng)函數(shù)以返回值返回或者當(dāng)函數(shù)以參數(shù)形式使用或者當(dāng)函數(shù)中自由變量在函數(shù)外被引用時(shí)才能成為明確意義上的閉包。 文章同步到github js的閉包概念幾乎是任何面試官都會(huì)問(wèn)的問(wèn)題,最近把閉包這塊的概念梳理了一下,記錄成以下文章。 什么是閉包 我先列出一些官方及經(jīng)典書(shū)籍等書(shū)中給出的概念,這些概念雖然...
摘要:變量的作用域無(wú)非就是兩種全局變量和局部變量。其中內(nèi)部函數(shù)中可以訪(fǎng)問(wèn)外部函數(shù)的變量,是因?yàn)閮?nèi)部函數(shù)的作用域鏈中包含了外部函數(shù)的作用域也可以理解為內(nèi)部函數(shù)的作用范圍輻射到了外部函數(shù)的作用范圍另一方面,在函數(shù)外部自然無(wú)法讀取函數(shù)內(nèi)的局部變量。 以前學(xué)習(xí)的時(shí)候,了解過(guò)變量提升和閉包,但是沒(méi)有深入了解,網(wǎng)上查了資料,這里記錄下,只供參考。部分內(nèi)容引用: https://www.cnblogs.c...
閱讀 2796·2023-04-25 14:41
閱讀 2404·2021-11-23 09:51
閱讀 3690·2021-11-17 17:08
閱讀 1682·2021-10-18 13:31
閱讀 5569·2021-09-22 15:27
閱讀 923·2019-08-30 15:54
閱讀 2235·2019-08-30 13:16
閱讀 743·2019-08-29 17:04