JavaScript核心——閉包,javascript核心
閉包(closure):有權訪問另一個函數範圍中的變數的函數。
建立閉包的常見方式就是在一個函數內部建立另一個函數(命名函數或匿名函數都行)。
我們以下面這個函數為例:
//定義一個用於比較兩個對象的函數,按照對象的某個屬性來比較function comparisonFunction(<span style="color:#FF0000;">propertyName</span>){return function(object1,object2){<span style="color:#FF0000;">var value1 = object1[propertyName];var value2 = object2[propertyName];</span>if(value1 < value2){return -1;} else if(value1 > value2){return 1;} else{return 0;}};}//建立函數var compareNameFunction = comparisonFunction("name");//調用比較函數var result = compareNameFunction({name:"zhu"},{name:"zhang"});//解除對匿名函數的引用,釋放記憶體compareNameFunction = null;包括那兩行紅色代碼的匿名函數就是一個閉包。它訪問了外部函數中的變數。
要理解比較,就先要理解函數的範圍鏈以及範圍的作用。這個在之前的文章講過。
當一個函數被調用時,會建立一個執行環境以及相應的範圍鏈。作用鏈域中的第一個對象就是本函數的使用中的物件,外部函數的使用中的物件始終處於第二位,外部函數的外部函數的使用中的物件處於第三位,.....直至作為範圍終點的全域執行環境。
還是以上面的代碼為例:
匿名函數從comparisonFunction()中被返回並且調用後,它的範圍鏈中包含了三個使用中的物件:它自己的使用中的物件,comparisonFunction函數的使用中的物件以及全域變數對象。
也就是說,雖然comparisonFunction()執行完了,其執行環境的作用鏈域會被銷毀,但它的的使用中的物件還會留在記憶體中,直到最後匿名函數被銷毀。
這也就是閉包的作用:
1.可以訪問函數內部的變數。
2.讓某些變數的值始終保持在記憶體中。
注意:閉包也有缺點,因為閉包會攜帶包含它的函數的範圍,因此會比其他函數佔用更多的記憶體。過度地使用閉包可能會導致記憶體佔用過多。