函数内部直接或间接调用函数本身为递归
递归求阶乘
function factorial(num) {
// 0的阶乘等于1
// 递归最重要的是明确递归结束条件,避免爆栈(RangeError: Maximum call stack size exceeded)
if (num === 0) return 1;
return num * factorial(num -1);
}
console.log(factorial(3)); // 6
console.log(factorial(2)); // 2
console.log(factorial(1)); // 1
console.log(factorial(0)); // 1
如果计算量特别大而导致爆栈,则可以使用尾递归,可惜的是除了Safari,其他的主流浏览器都还未能实现对尾递归的支持
'use strict';
// 按照规范, 只要使用了尾递归就不会发生栈溢出
// 但必须在严格模式下运行代码
function factorial(num, total = 1) {
// 使用total累计计算结果
if (num === 0) return total;
// 所有的递归都必须再尾部调用, 不允许计算,
// return后面只能跟函数调用
return factorial(num - 1, num * total);
}
console.log(factorial(3)); // 6
console.log(factorial(2)); // 2
console.log(factorial(1)); // 1
console.log(factorial(0)); // 1
console.log(factorial(1000)); // Infinity
// 暂不支持, 所以依旧溢出
console.log(factorial(10000));
// RangeError: Maximum call stack size exceeded
使用递归简单模拟for循环
function forLoop(arr, i, limit, fn) {
(function inner(i) {
if (i >= limit) return;
fn(arr[i], i, arr);
inner(++i);
})(i);
}
const arr = [1, 3, 5, 2, 7, 8];
const res = [];
forLoop(arr, 0, arr.length, (val, idx, arr) => {
res.push(val * 2);
});
console.log(res);
// [ 2, 6, 10, 4, 14, 16 ]
使用递归计算斐波那契数列
// 计算第n个斐波那契数字
function fib(n) {
if (n === 0) return 0;
if (n === 1) return 1;
return fib(n - 1) + fib(n - 2);
}
// 获取前n个斐波那契数字
function getAllFib(n) {
const res = Array(n);
for (let i = 0; i < n; i++) {
res[i] = fib(i);
}
return res;
}
console.log(getAllFib(10));
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]