在使用JavaScript遞歸調用時,咱們每每會在函數內部調用函數自身(經過函數名),可是當咱們改變了定義時所用函數名的指向時,那麼這個遞歸函數指針關聯的遞歸函數也將隨之失效。
var factorial = function (num) { if (num <= 1) { return 1; } else { return num * factorial(num - 1); } }; console.log(factorial(5)); // 120; var anothorFactorial = factorial; factorial = null; console.log(anothorFactorial(5)); // Uncaught TypeError: factorial is not a function
在非嚴格模式下咱們能夠使用 num * arguments.callee(num - 1)來代替函數名。
嚴格模式下,一般會採用內聯命名函數來解決這個問題。函數
var factorial = (function f(num) { if (num <= 1) { return 1; } else { return num*f(num - 1); } }); console.log(factorial(5)); // 120 var anothorFactorial = factorial; factorial = null; console.log(anothorFactorial(5)); // 120
這種方式的函數調用區別於下面這種方式:指針
function f(num) { if (num <= 1) { return 1; } else { return num*f(num - 1); } }; var factorial = f; var anothorFactorial = factorial; factorial = null; console.log(anothorFactorial(5)); // 120 f = null; console.log(anothorFactorial(5)); // Uncaught TypeError: f is not a function
給函數表達式的匿名函數命名並不會改變表達式的性質,即不會讓它變成一個函數聲明code
var factorial = function f() { console.log(factorial == f); // true } factorial(); //true console.log(typeof f); // undefined f(); // Uncaught ReferenceError: f is not defined
上述代碼證實:儘管咱們能夠給內聯函數命名,可是這些名稱只能在自身函數內部纔是可見的。使用內聯方式調用,其本質和函數表達式沒有太大不一樣,惟一的區別就是內聯命名函數在函數內部提供了一個僅僅可供自身調用的函數指針,該指針指向函數自身。遞歸