JS递归函数详解

时间:2025-05-09 07:21:44

文章目录

  • 一、什么是递归函数
  • 二、递归函数实现的基本思路
  • 三、递归函数的注意点
  • 四、递归案例
    • 2.1、1~n的累加和
    • 2.2、求n的阶乘
    • 2.3、递归求斐波那契数列
  • 五、经典面试题以及推荐用法

一、什么是递归函数

简单来说,递归函数就是一个函数直接或间接地调用自身

二、递归函数实现的基本思路

  • 设定好函数的功能(包括参数和返回值的设计),这是最关键的一环。
  • 将自身作为一个普通函数来调用,认定它能完成它的工作。
  • 调用自身时给的参数不能和自己的完全相同。
  • 将一个最简单的情况作为结束条件,放在调用自身之前。
  • 检查结束条件是否有疏漏。

三、递归函数的注意点

  • 一定要有结束条件,否则会导致死循环
  • 能用递归函数实现的需求,就一定可以用循环调用函数来解决,只是代码简洁与性能不同而已

四、递归案例

2.1、1~n的累加和

递归写法

function sum(n) {
  //传递进来的是5
  //当n==1的时候结束
  if (n == 1) {
    return 1;
  }
  //不满足条件的时候,就是当前数字 + 比自己小 1 的数字
  return n + sum(n - 1);
}
(sum(5)); // 15

循环写法

function getSum(n) {
  var data = 0;
  for (var i = 1; i <= n; i++) {
    data += i;
  }
  return data;
}

2.2、求n的阶乘

递归写法

function fn(n) {
  // n 就是你要求的终点
  if (n === 1) {
    // 设置终点位置
    return 1;
  }
  // 当 n 不是 1 的时候
  // 就递进去
  return n * fn(n - 1);
}
fn(3); // 6

循环写法

function getMul(n) {
  var data = 1;
  for (var i = 1; i <= n; i++) {
    data *= i;
  }
  return data;
}

2.3、递归求斐波那契数列

斐波那契数列指的是这样一个数列:1 1 2 3 5 8 13 21 34 55 …这个数列从第3项开始,每一项都等于前两项之和
递归写法

function fn(n) {
  // n 就是要求的第 n 位
  //  设置终点
  if (n === 1 || n === 2) {
    return 1;
  }
  // 未到终点
  return fn(n - 1) + fn(n - 2);
}
(fn(10)); // 55

循环写法

function getData(n) {
  var arr = [1, 1];
  for (var i = 2; i < n; i++) {
    arr[i] = arr[i - 1] + arr[i - 2];
  }
  (arr); //[1,1,2,3,5,8,13,21,34,55]
  return arr[ - 1];
}

五、经典面试题以及推荐用法

var res = (function (n) {
  return n == 1 ? 1 : n * (n - 1);
})(6);
("res" + res); //res720

考察的知识点: 是一个指向正在执行的函数的指针,使用它来代替函数名,可以确保无论怎样调用函数都不会出问题

function res(n) {
  return n == 1 ? 1 : n * res(n - 1);
}
var data = res;
res = null;
(data(4));
//res is not a function

由于res变量设置为Null,结果指向原始函数的引用只剩下一个,res已经不是函数,而调用data()会执行res,所以会报错;而使用可以解决这个问题

function res(n) {
  return n == 1 ? 1 : n * (n - 1);
}
var data = res;
res = null;
(data(4)); //24

推荐用法
严格模式:使用会报错吗,不过我们可以通过命名函数表达式来达到相同的效果
以下代码创建了一个f()的命名函数表达式,赋值给res变量,即使把函数赋值给另一个变量,函数的名字依然有效,递归能正常完成,这种方式在严格模式和非严格模式都能运行

var res = function f(n) {
  return n == 1 ? 1 : n * f(n - 1);
};
(res(4)); //24