要理解閉包,首先要先理解javascript變量的做用域 變量的做用域只有兩種:全局變量 + 局部變量javascript
全局變量:任何地方均可以訪問(函數內部、外部) 局部變量:只能在變量所在函數及函數的子函數中訪問 :fa-exclamation-circle:注意:變量聲明若是不使用var關鍵字,那麼他就是一個全局變量,即便是在函數內部定義java
但願計算器的值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的閉包就能夠解決該問題。性能
在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
當函數a的內部函數b被函數a外的一個變量引用的時候,就建立了一個閉包。 閉包就是將函數內部和函數外部鏈接起來的一座橋樑作用域
計算機困境能夠更改成如下兩種方式:
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回收。
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; } }