說到 閉包 ,這是js不得不提的一個特性,很多傳統語言都不具備這樣的特性,比如JAVA C等等。
之前看書的時候,總是理解不好什么是閉包!下面就通過手繪一張原理圖,來理解一下:
首先基本上所有的編程語言都有類似的特性,局部方法可以訪問外部父類方法的屬性,也就是說,子類或子方法可以訪問父類的資源。
<!-- 在正常的腳本中,某個方法可以獲取到外部的變量,或者全局變量 --> var num = 11; function func1(){ console.log(num); } func1();
因此上面的這段代碼,我們可以獲取到num的值。
父類能否獲取到子方法內部的值呢?
function func2(){ var num1 = 22; num2 = 33; } func2(); <!--console.log(num1); 會報錯!--> console.log(num2); <!--可以獲取到num2的值,因為不使用var定義變量時,默認是全局變量 -->
當然是不可以的,因為子方法的變量作用域僅僅是子方法的范圍,外部是無法獲取到的。
那么如何才能在外部獲取到子方法的局部變量呢!
如果是java,一個類的私有屬性,可以通過公共的get方法來獲取,比如:
class Person{ private String name; public String getName(){ return name; } }
通過上面的方式可以獲取到一個類內部的私有屬性,同樣的,在js中可以通過某個方法來獲取這個方法的局部變量,然后通過這個方法內的方法來讀取想要的變量值。
function func3(){ var num3 = 44; function func4(){ return num3; } return func4; } var func = func3(); console.log(func());
參考下面的圖解:
在外部無法獲取到func3內部的局部變量,但是func3內部的局部方法func4卻可以獲取到,因此 返回一個func4的引用 ,這樣在外部通過這個func4就可以獲取到func3的內部變量。
雖然是繞了一個圈子,但是在方法外部卻通過這樣一個手段獲取到了內部的值。
而這個方法內的局部方法func4就叫做閉包,按照很多書上的概念,這個方法搭建了方法內部與方法外部的橋梁,使得在外部也可以任意的獲取到方法內部的資源。
但是閉包會造成變量在內存中持久占用,因此會有一定的性能問題,最好不要輕易使用,即便使用也要在恰當的實際進行釋放。
示例的源碼:
<!doctype html> <html> <head> </head> <body> <script type="text/javascript"> <!-- 在正常的腳本中,某個方法可以獲取到外部的變量,或者全局變量 --> var num = 11; function func1(){ console.log(num); } func1(); <!-- 但是在外部是無法獲取方法內部的局部變量的 --> function func2(){ var num1 = 22; num2 = 33; } func2(); <!--console.log(num1); 會報錯!--> console.log(num2); <!--可以獲取到num2的值,因為不適用var定義變量時,默認是全局變量 --> <!-- 那么如何在外部獲取到內部的變量呢!javascript可以辦到 --> function func3(){ var num3 = 44; function func4(){ return num3; } return func4; } var func = func3(); console.log(func()); </script> </body> </html>
運行結果: