1⃣️遞歸html
階乘函數:閉包
function factorial(num){ if (num <= 1){ return 1; } else { 6 return num * factorial(num-1); } }
改裝一:(arguments.callee指向正在執行的函數的指針,實現解耦)函數
function factorial(num){ if (num <= 1){ return 1; } else { return num * arguments.callee(num-1); } }
改裝二:(解決嚴格模式下不能使用arguments.callee)spa
var factorial = (function f(num){ if (num <= 1){ return 1; } else { return num * f(num-1); } });
2⃣️閉包的做用域鏈指針
function createComparisonFunction(propertyName) { return function(object1, object2){ var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2){ return -1; } else if (value1 > value2){ return 1; } else { return 0; }
}; }
var compare = createComparisonFunction("name"); var result = compare({ name: "Nicholas" }, { name: "Greg" });
在匿名函數從 createComparisonFunction()中被返回後,它的做用域鏈被初始化爲包含 createComparisonFunction()函數的活動對象和全局變量對象。code
so,compare的做用域鏈包含createComparisonFunction函數的活動對象(局部函數和局部屬性,上述代碼沒有體現出來)和全局變量對象.看下面的例子:htm
var count = 100; var a = 2; function create(){ var count = 10; return function(){ console.log(count + a); } }; var b = create(); b();
這是一個典型的閉包,就像上面所說,b的做用域鏈被初始化爲create函數的活動對象(count=10)和全局變量(a=2,count=100);因此執行b()的時候,count+a=10+2=12;對象
爲何是10+2,而不是100+2?請看這篇博客:js做用域鏈.blog
注意:遞歸
createComparisonFunction() 函數在執行完畢後,其活動對象也不會被銷燬,由於匿名函數的做用域鏈仍然在引用這個活動對象。換句話說,當createComparisonFunction()函數返回後,其執行環境的做用域鏈會被銷燬,但它的活動對象仍然會留在內存中;直到匿名函數被銷燬後,createComparisonFunction()的活動對象纔會被銷燬.
也就是說,上述代碼所示,局部變量count會一直留在內存中,除非手動解除對匿名函數的引用
create = null;