Javascript之【閉包】

1. 變量做用域

要理解閉包,首先要先理解javascript變量的做用域 變量的做用域只有兩種:全局變量 + 局部變量javascript

全局變量:任何地方均可以訪問(函數內部、外部) 局部變量:只能在變量所在函數及函數的子函數中訪問 :fa-exclamation-circle:注意:變量聲明若是不使用var關鍵字,那麼他就是一個全局變量,即便是在函數內部定義java

1.1 計算器困境

但願計算器的值counter可以被修改,可是不但願被任意更改(只能+1) 全局變量實現:閉包

var counter = 0;
    function add(){
        ++counter;
    }
		
    add(); //1
    add(); //2
    add(); //3
    問題:counter的值能夠被任意更改。

局部變量實現:函數

function add(){
        var counter = 0;
        ++counter;
    }
		
    add(); //1
    add(); //1
    add(); //1
    問題:counter的值不能按照設想來正確輸出。

javascript的閉包就能夠解決該問題。性能

2. javascript內嵌函數

在javascript中,全部的函數都可以訪問它們上層的做用域code

function add(){
    var counter = 0;
    function plus(){
        ++counter;
    }
}

上面代碼中,plus函數在add函數內部,這使得add內部的全部局部變量都是對plus可見的,可是反過來卻不行。 這就是javascript語言特有的【鏈式做用域】結構(chain scope)ip

若是咱們可以在外部訪問plus函數,那麼這個【計算機困境】就可以解決了 因此,只要將plus函數做爲add函數的返回值,就能夠訪問plus函數了, 也就能夠經過plus函數,在add函數外部訪問add函數局部變量了內存

================ 以上所說就是閉包。ci

3. javascript中的閉包

當函數a的內部函數b被函數a外的一個變量引用的時候,就建立了一個閉包。 閉包就是將函數內部和函數外部鏈接起來的一座橋樑作用域

3.1 閉包的用途:
  1. 能夠讀取函數內部的變量
  2. 可讓函數內部變量的值始終保存在內存中

計算機困境能夠更改成如下兩種方式:

1:(建議)
var add = (function(){
    var counter = 0;
    return function plus(){return ++counter;}
})();

add(); //1
add(); //2
add(); //3

2:
function add(){
    var counter = 0;
    return function plus(){return ++counter;}
    }
		
    var f1 = add(); 
    f1(); //1
    f1(); //2
    f1(); //3

以上證實:局部變量counter一直在內存中, 並無在函數執行完後自動清除。 why?????? because: --add是plus的父函數,而plus被賦給了一個全局變量,致使plus始終在內存中, 而plus函數依賴於add函數,因此add也一直在內存中,不會再結束後被GC回收。

3.2 getter/setter
function add(){
    var counter = 0;
    getCounter = function(){
        reutrn counter;
    }
}

注意add中的getCounter變量,由於沒有使用var來聲明,因此它是一個全局變量, 能夠當作java中的getter來使用 :fa-hand-o-down:

public class add{
    private int counter = 0;
    public int getCounter(){
        return counter;
    }
}
3.3 閉包應該注意的問題
  1. 因爲閉包使得函數中的變量,都被保存在內存中,內存消耗很大,因此不能濫用閉包。 不然會形成網頁性能問題,甚至會內存泄漏。 解決方案:退出函數以前,將不使用的局部變量所有消除(變量的值爲null便可)。
  2. 若是把函數當作Object使用,不要隨便經過setter/閉包改變函數內部的變量值。
相關文章
相關標籤/搜索