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

資訊專欄INFORMATION COLUMN

Javascript閉包,結(jié)合Javascript回收機制

why_rookie / 915人閱讀

摘要:第二段代碼由于匿名函數(shù)并沒有被外的其他地方所引用,所以在函數(shù)執(zhí)行完畢后,其活動對象也跟隨的執(zhí)行環(huán)境的銷毀而銷毀。

話不多說先來看兩段代碼

function a(){
 var num=10;
 return function(){
    console.log(num++)
    }
}
var b=a();
b();  //10
b();  //11
b();  //12
b=null; //手動釋放內(nèi)存,消除對匿名函數(shù)的引用
function a(){
 var num=10;
 return function(){
    console.log(num++)
    }
}
a()(); //10
a()(); //10
a()(); //10

下面開始講解代碼:
在講解之前,首先請了解一下關(guān)于函數(shù)作用域方面的知識,可以參考本人之前寫的一片短文https://segmentfault.com/a/11...

//當函數(shù)a定義時 會創(chuàng)建一個[[scope]]屬性,僅供javascript引擎內(nèi)部使用
//偽代碼
a.[[scope]]={
  GO:{     //全局對象globel object
    this:window,
    window:{...},
    document:{...},
    a:(function)
    ...
    }     
}

當函數(shù)a調(diào)用的時候,會創(chuàng)建一個a的執(zhí)行環(huán)境,每個執(zhí)行環(huán)境對應一個變量對象。首先會創(chuàng)一個它自己的活動對象【Activation Object】(這個對象中包含了this、參數(shù)(arguments)、局部變量(包括命名的參數(shù))的定義,當然全局對象是沒有arguments的)和一個變量對象的作用域鏈[[scope chain]],然后,把這個執(zhí)行環(huán)境的[[scope]]按順序復制到[[scope chain]]里,最后把這個活動對象推入到[[scope chain]]的頂部。這樣[[scope chain]]就是一個有序的棧,這樣保了對執(zhí)行環(huán)境有權(quán)訪問的所有變量和對象的有序訪問。

//函數(shù)調(diào)用時候
a.ex={   //a的執(zhí)行環(huán)境,包括a的活動對象和a的作用域鏈
 AO:{
    this:window,
    arguments:[],
    num:undefined
    },
 [[scope chain]]:{
    AO:當前函數(shù)活動對象,
    GO:{...}  //全局對象,從a.[[scope]]中復制過來的
    }
//進入a的執(zhí)行環(huán)境時,匿名函數(shù)被定義.
匿名函數(shù).[[scope]]={
    AO:{    //函數(shù)a的活動對象
       this:window,
       arguments:[],
       num:undefined
    },
    GO:{...}
}

關(guān)鍵點來了
上述兩段代碼中:
第一段代碼在執(zhí)行a()的時候,將a函數(shù)返回的匿名函數(shù)賦給了變量b,并且連續(xù)調(diào)用三次b
第二段代碼在執(zhí)行a()的時候,沒有對a函數(shù)返回的匿名函數(shù)進行賦值。
在Javascript中,如果一個對象不再被引用,那么這個對象就會被GC回收。如果兩個對象互相引用,而不再被第3者所引用,那么這兩個互相引用的對象也會被回收。
第一段代碼因為函數(shù)a的活動對象被匿名函數(shù)的[[scope]]引用,匿名函數(shù)又被a外的變量b引用,所以在全局環(huán)境下始終保持對a活動對象的引用,所以a的活動對象無法被回收。
第二段代碼由于匿名函數(shù)并沒有被a外的其他地方所引用,所以在函數(shù)a執(zhí)行完畢后,其活動對象也跟隨a的執(zhí)行環(huán)境的銷毀而銷毀。
用圖表示


值得注意的是,雖然執(zhí)行環(huán)境和函數(shù)scope屬性中都保存這作用域鏈,但這兩個并不是一個性質(zhì)的。
明確一點區(qū)別
[[Scope]]屬性是函數(shù)創(chuàng)建時產(chǎn)生的,會一直存在
而執(zhí)行環(huán)境在函數(shù)執(zhí)行時產(chǎn)生,函數(shù)執(zhí)行結(jié)束便會銷毀

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81105.html

相關(guān)文章

  • 理解閉包

    摘要:歡迎移步我的博客閱讀理解閉包閉包是指可以包含自由未綁定到特定對象變量的代碼塊這些變量不是在這個代碼塊內(nèi)或者任何全局上下文中定義的,而是在定義代碼塊的環(huán)境中定義局部變量。 歡迎移步我的博客閱讀:《理解閉包》 閉包 是指可以包含自由(未綁定到特定對象)變量的代碼塊;這些變量不是在這個代碼塊內(nèi)或者任何全局上下文中定義的,而是在定義代碼塊的環(huán)境中定義(局部變量)。閉包 一詞來源于以下兩者的結(jié)...

    用戶83 評論0 收藏0
  • 前端基礎進階(四):詳細圖解作用域鏈與閉包

    摘要:之前一篇文章我們詳細說明了變量對象,而這里,我們將詳細說明作用域鏈。而的作用域鏈,則同時包含了這三個變量對象,所以的執(zhí)行上下文可如下表示。下圖展示了閉包的作用域鏈。其中為當前的函數(shù)調(diào)用棧,為當前正在被執(zhí)行的函數(shù)的作用域鏈,為當前的局部變量。 showImg(https://segmentfault.com/img/remote/1460000008329355);初學JavaScrip...

    aikin 評論0 收藏0
  • 淺談對JavaScript閉包的理解

    摘要:關(guān)于循環(huán)和閉包當循環(huán)和閉包結(jié)合在一起時,經(jīng)常會產(chǎn)生讓初學者覺得匪夷所思的問題。閉包是一把雙刃劍是比較難以理解和掌握的部分,它十分強大,卻也有很大的缺陷,如何使用它完全取決于你自己。 在談閉包之前,我們首先要了解幾個概念: 什么是函數(shù)表達式? 與函數(shù)聲明有何不同? JavaScript查找標識符的機制 JavaScript的作用域是詞法作用域 JavaScript的垃圾回收機制 先來...

    missonce 評論0 收藏0
  • javascript塊級作用域處理閉包和釋放內(nèi)存的垃圾回收

    摘要:然而,引擎很可能雖然這要看具體實現(xiàn)將會仍然將這個結(jié)構(gòu)保持一段時間,因為函數(shù)在整個作用域上擁有一個閉包。 內(nèi)容 平時編寫代碼的時候很少關(guān)注細節(jié),對javascript深層也沒具體了解,下面針對平時寫代碼的形式分析、調(diào)整完善自己的代碼,這里以一個簡單例子分析js作用域和垃圾回收機制,通過塊級作用域處理一些細節(jié),提升自己代碼性能。 普通案例 在日常中最常見的代碼編寫方式: function ...

    vpants 評論0 收藏0
  • javascript高級程序設計》筆記:內(nèi)存與執(zhí)行環(huán)境

    摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當我們在程序中創(chuàng)建一個對象時,這個對象將被保存到運行時數(shù)據(jù)區(qū)中,以便反復利用因為對象的創(chuàng)建成本通常較大,這個運行時數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級程序設計》筆記:繼承近幾篇博客都會圍繞著圖中的知識點展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...

    fuyi501 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<