成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

js閉包的理解

EasonTyler / 3452人閱讀

摘要:一般來(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)元素的索引





    
    
    



    
  • a
  • b
  • c
  • d

執(zhí)行以上代碼發(fā)現(xiàn)點(diǎn)擊任何一個(gè)返回的都是4,這是因?yàn)橘x值的時(shí)候,傳的i是對(duì)內(nèi)存地址的引用,循環(huán)結(jié)束,i指向的就是4.

使用閉包改寫(xiě)上面的代碼





    
    閉包
    



    
  • a
  • b
  • c
  • d

每一次循環(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

相關(guān)文章

  • 談?wù)勎宜?em>理解閉包,js、php、golang里closure

    摘要:當(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、...

    betacat 評(píng)論0 收藏0
  • 談?wù)勎宜?em>理解閉包,js、php、golang里closure

    摘要:當(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、...

    zhoutao 評(píng)論0 收藏0
  • 理解 JavaScript 閉包

    摘要:如何在初學(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...

    寵來(lái)也 評(píng)論0 收藏0
  • JavaScript中閉包

    摘要:閉包引起的內(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ū)中給出的概念,這些概念雖然...

    HmyBmny 評(píng)論0 收藏0
  • js 變量提升和閉包理解

    摘要:變量的作用域無(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...

    luoyibu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<