帶着疑問來理解JavaScript閉包是如此簡單

前言

在JavaScript中,閉包對於JavaScript的意義無異於指針在c++中的意義。理解閉包是我們掌握JavaScript這門語言的基礎能力,而對閉包的掌握程度就可以看出來你對JavaScript這門語言的深入程度,網上關於閉包的文章也不少但多數讓人看過之後一頭霧水,也許是自己理解能力較差。所以我還下定決心以提問的方式來理解何謂閉包,希望能給與我有相同境遇的博友一點幫助。

閉包是什麼

  1. 基本概念(一句話來表述:當B執行時,如果訪問了A中變量對象中的值,那麼閉包就會產生)
    • 閉包是指有權訪問另一個函數作用域中的變量函數,即B函數爲閉包函數。
  2. 特徵:
    • 函數嵌套函數。
    • 函數內部可以引用外部的參數和變量。
    • 參數和變量不會被垃圾回收機制回收。

關於閉包的疑問

1. 爲什麼函數內部可以引用外部的參數和變量?

  • javascript中作用域鏈決定的變量的引用。(作用域鏈是由一系列變量對象組成,我們可以在這個單向通道中,查詢變量對象中的標識符,這樣就可以訪問到上一層作用域中的變量了。)

2. 爲什麼參數和變量不會被垃圾回收機制回收?

  • 在JavaScript的作用域的規則是根據標識符名稱進行變量查找。
  • 函數在調用激活時,會開始創建對應的執行上下文,在執行上下文生成的過程中將確定變量調用的作用域鏈。
  • 正常來說函數執行完後,其對應使用的內存會被JavaScript的垃圾回收機制自動回收(如何回收不在此解釋,簡單來說就是變量不在被引用則會被自動回收),但是閉包不會如此請看如下代碼。
var a = 20;
function clour(c) {
    var b = a + c;
    function innerTest() {
        return b + c;
    }
    return innerTest();
}

var result =clour();//全局變量result不會被回收,並且innerTest被其引用也不會被回收


以上就是爲何閉包是能保存變量不被回收。因爲閉包內部的變量被一直引用着,JavaScript的垃圾回收機制決定了這種情況不會被回收的。

項目中閉包常見的運用

  1. 最常見的應用-模塊化
;(function(global, factory) {
    factory(global);
}(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
    
    var jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context );
    };
    jQuery.fn = jQuery.prototype = {};
    //......
    if ( typeof noGlobal === strundefined ) {
        window.jQuery = window.$ = jQuery;
    }

    return jQuery;
})); 

看到這段代碼大家是不是覺的很熟悉,相信只要是前端都用過他jquery,但是有幾人仔細研究過jquery的源碼呢(反正我沒有=-=)。細節我們就不多說了,這種整體架構我們瞅瞅就曉得用了閉包。這也是前端模塊化非常成功的一個實例,雖然現在已經漸漸退出前端界,但是現在比較火的vue(reactjs源碼沒看過不確定是否也使用了這種結構)中,模塊化很常見。

  1. 最常見的應用-定時器
setTimeout(function(){
    console.log('this is time out')
},1000)
  1. 最常見的應用-柯里化傳送門
// 正常函數
function normal(a, b) {
    return x + y
}

// 柯里化函數
function curry(x) {
    return function (y) {
        return x + y
    }
}

normal(2, 2)           // 4
curry(21)(2)   // 4

函數可以作爲參數進行傳遞,並且將函數作爲返回值return出去。

總結

道可道非常道。名可名非常名。在javascript語言世界中有許多特性需要我們自己去理解,別人告訴你的是他們站在自己的角度思考得出的結論,這點我們只能作爲參考來看,這也是我爲何要寫這篇文章,不只是爲了給別人分享下自己對JavaScript閉包的理解也是自己對閉包這塊的一個總結吧,如有不正之處請文明指正。

注:本文參考的文檔前端基礎進階(四):詳細圖解作用域鏈與閉包作者前端基礎進階系列文章通俗易懂值得一讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章