標籤:
六、函數運算式
//把函數當成值來使用的情況下,都可以使用匿名函數
- 遞迴
//遞迴函式是在一個函數通過名字調用自身的情況下構成的//使用函式宣告來定義遞迴函式可能會出現問題//這是一個經典的遞迴階乘函數function factorial(num) { if (num<1){ return 1; }else{ return num * factorial(num-1); }}//使用函數聲名來定義該遞迴函式時,函數名和函數體會產生耦合。//當其他指標指向該函數體的時候,由於執行anotherFac()必須執行factorial,而factorial變數已經設為null,就會導致錯誤var anotherFac = factorial;factorial = null;anotherFac(5);//可以用arguments.callee來解決該問題,不在贅述//也可以將命名函數運算式賦值給變數factorial,這種解決辦法在strict 模式下依然有效
- 閉包
閉包是指有權訪問另一個函數範圍中的變數的函數(最常見的表現形式是從一個函數中返回另一個函數),容易和匿名函數搞混。在函數被調用時,會建立一個執行環境及相應的範圍鏈。由該函數的arguments和其他具名引數的值初始化的使用中的物件排在範圍鏈的第一位,外部函數的使用中的物件則始終處於第二位,而最外層則是全域變數對象。一般情況下當函數執行完畢後,拒不使用中的物件就會被銷毀,記憶體中僅儲存全域變數對象,但是閉包的情況由有所不同。閉包會攜帶包含它的函數範圍,比其他函數佔用更多記憶體。所以要慎用閉包。凡是匿名函數的this都是指向window。Javascript沒有塊級範圍的概念,所以在語句塊中定義的活動變數的範圍會擴大到整個函數體。可以用匿名函數(function(){})()來避免這種情況。解釋(function(){})()的問題在185頁。私人變數能夠協助理解為什麼對象的建構函式長那個樣子。初始化未經聲明的變數,總是會建立一個全域變數。(這也是函式宣告和函數運算式的不同之處,函式宣告只能建立局部函數)
JavaScript進階程式設計:第七章 - 函數