標籤:get 擷取 method class 外部串連 return win array value
閉包:閉包是指有權訪問另一個函數範圍中的變數的函數,建立閉包的常見方式是 在一個函數內部建立另一個函數
(從定義上講 js 中所有的函數都是閉包)
function a(){ var i=0; function b(){ alert(++i); } return b;}var c=a();c();
以上代碼的特點:
1、函數b嵌套在函數a內部;
2、函數a返回函數b。
當函數a的內建函式b被函數a外的一個變數引用的時候,就建立了一個閉包。
閉包就是函數或代碼塊執行完後不回收a中佔用的資源,因為a的內建函式的執行需要依賴a中的變數
PS:全域環境的變數對象始終存在,像函數中的局部環境變數,則只在函數執行的過程中存在
範圍鏈本質上是一個指向變數對象的指標列表,它只引用但不實際包含變數對象。
PS: 由於閉包會攜帶包含它的函數的範圍,因此會比其他函數佔用更多的記憶體。過渡使用閉包可能會導致記憶體佔用過多
所以,在本質上,閉包就是將函數內部和函數外部串連起來的一座橋樑。
閉包的用處:
a.讀取函數內部的變數。
b.讓這些變數的值始終保持在記憶體中。
使用閉包的注意點
1)由於閉包會使得函數中的變數都被儲存在記憶體中,記憶體消耗很大,所以不能濫用閉包,
否則會造成網頁的效能問題,在IE中可能導致記憶體泄露。解決方案是,在退出函數之前,將不使用的局部變數全部刪除。
2)閉包會在父函數外部,改變父函數內部變數的值。所以,如果你把父函數當作對象(object)使用,
把閉包當作它的公用方法(Public Method),把內部變數當作它的私人屬性(private value),
這時一定要小心,不要隨便改變父函數內部變數的值。
閉包容易造成的問題:
function a(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(num){ return function(){ return num; }; }(i); //若此處不傳入 i值 運行代碼後 擷取的值 都是 10 } return result;}
var name = "The Window";var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; }};alert(object.getNameFunc()()); //"The Window"(在非strict 模式下)
object.getNameFunc() 執行後 返回的是一個函數 後面的括弧又運行了該函數 相當於該函數是在全域環境中啟動並執行。
在全域環境中this 預設指向的是window對象
所以函數裡面的this.name 就是全域的變數name
解決辦法:
我們知道,閉包的一個作用就是讀取函數內部的變數。
如果要擷取本來的對象 可以將本來的this 儲存在另一個自訂的變數中 然後將該變數傳入返回的函數裡面。
這樣該變數就會一直儲存在記憶體中 不會被銷毀
js 中的閉包