前端 JS 经典:递归

简介: 前端 JS 经典:递归

1. 什么是递归

函数内部调用自己,这就是递归

2. 为什么用递归

对数据进行处理,优化处理流程可以用递归

3. 构成递归三要素(必须)

3.1 参数递归逻辑:如下例,demo(n-1)对比 demo(n)参数递归逻辑为 n-1

3.2 临界值:如下例,n == 0,不再递归

3.3 递归业务逻辑:如下例,n + demo(n-1),0 到 n 求和

// 例子
function demo(n) {
  if (n == 0) return 0;
  return n + demo(n - 1);
}

4. 经典递归案例

// 4.1:0 到 n 求和
function sum(n) {
  // sum(n-1) n-1 为参数递归的逻辑
  // n == 1 为临界值
  // n + sum(n-1) 为递归业务逻辑
 
  if (n == 1) return 1;
  return n + sum(n - 1);
}
sum(100); // 5050
 
// 4.2:数组扁平化
// 将[1, [2, 3], [4, [5, 6]], 7]转换为[1, 2, 3, 4, 5, 6, 7]
function flattenArray(arr) {
  // arr.forEach(item => { flattenArray(item) }) 数组遍历的item,为参数递归的逻辑
  // !Array.isArray(item) 不是数组时,为临界值
  // resultArr.push(...flattenArray(item)) 将数组拼接起来, 为递归业务逻辑
 
  const resultArr = [];
  arr.forEach((item) => {
    if (!Array.isArray(item)) {
      resultArr.push(item);
    } else {
      resultArr.push(...flattenArray(item));
    }
  });
  return resultArr;
}
flattenArray([1, [2, 3], [4, [5, 6]], 7]); // [1, 2, 3, 4, 5, 6, 7]
 
// 4.3:深拷贝
function deepClone(obj) {
  // for (const key in obj) { deepClone(obj[key]) } 遍历的obj[key],为参数递归的逻辑
  // typeof v === "object" && v !== null 是对象类型且不为null继续递归,反之则为临界值
  // target[key] = deepClone(v) 为递归业务逻辑
 
  // 拷贝数据不是对象类型直接返回
  if (typeof obj !== "object") return obj;
  const target = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    // 判断数据中key是否重复,不重复着继续逻辑
    if (!hasOwnProperty.call(obj, key)) continue;
    const v = obj[key];
    target[key] = typeof v === "object" && v !== null ? deepClone(v) : v;
  }
  return target;
}
 
// 4.4:斐波拉契数列
// 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...求第 n 项
function fib(n) {
  // fib(n-1),fib(n-2) 第n位数为第n-1位数+第n-2位数,n-1,n-2为参数递归的逻辑
  // n == 1 || n == 2 第1位数为1,第二位数为1,n==1,n==2为临界值
  // fib(n-1) + fib(n-2) 第n位数为第n-1位数+第n-2位数,为递归业务逻辑
 
  if (n == 1 || n == 2) return 1;
  return fib(n - 1) + fib(n - 2);
}
 
// 4.5:爬楼梯
// 一个人爬楼梯,只可以一步走1层或一步走2层,到达n层,一共多少种走法?
// 1, 2, 3, 5, 8; 爬1层1种走法,2层2种,3层3种,4层5种,5层8种,...n层n-1层+n-2层走法
function climbStairs(n) {
  // n-1,n-2 为参数递归的逻辑
  // n == 1 || n ==2 为临界值
  // climbStairs(n-1) + climbStairs(n-2) 为递归业务逻辑
 
  if (n == 1 || n == 2) return n;
  return climbStairs(n - 1) + climbStairs(n - 2);
}


目录
相关文章
|
14天前
|
前端开发 JavaScript 数据处理
前端新手指南:如何解决JavaScript导出CSV文件不完整的问题
【6月更文挑战第4天】在JavaScript中处理CSV文件时,需要特别注意一些特殊字符,例如逗号、双引号、换行符等。这些字符可能会影响CSV文件的解析,导致数据错乱。
49 0
|
10天前
|
前端开发 JavaScript 安全
高级前端开发需要知道的 25 个 JavaScript 单行代码
1. 不使用临时变量来交换变量的值 2. 对象解构,让数据访问更便捷 3. 浅克隆对象 4. 合并对象 5. 清理数组 6. 将 NodeList 转换为数组 7. 检查数组是否满足指定条件 8. 将文本复制到剪贴板 9. 删除数组重复项 10. 取两个数组的交集 11. 求数组元素的总和 12. 根据指定条件判断,是否给对象的属性赋值 13. 使用变量作为对象的键 14. 离线状态检查器 15. 离开页面弹出确认对话框 16. 对象数组,根据对象的某个key求对应值的总和 17. 将 url 问号后面的查询字符串转为对象 18. 将秒数转换为时间格式的字符串 19.
20 3
高级前端开发需要知道的 25 个 JavaScript 单行代码
|
14天前
|
JavaScript 前端开发 网络协议
前端JS发起的请求能暂停吗?
在讨论前端JS发起的请求是否能暂停时,需要明确两个概念:什么状态可以被认为是“暂停”?以及什么是JS发起的请求?
74 1
前端JS发起的请求能暂停吗?
|
4天前
|
设计模式 前端开发 JavaScript
关于写好前端JS代码的一些建议
关于写好前端JS代码的一些建议
17 2
|
6天前
|
JavaScript 前端开发 测试技术
了解JS递归
了解JS递归
13 1
|
13天前
|
JavaScript Serverless
JS实现递归功能
JS实现递归功能
|
13天前
|
XML 前端开发 JavaScript
前端简介(HTML+CSS+JS)
前端简介(HTML+CSS+JS)
|
17天前
|
前端开发 JavaScript 安全
TypeScript作为一种静态类型的JavaScript超集,其强大的类型系统和面向对象编程特性为微前端架构的实现提供了有力的支持
【6月更文挑战第11天】微前端架构借助TypeScript提升开发效率和代码可靠性。 TypeScript提供类型安全,防止微前端间通信出错;智能提示和自动补全加速跨代码库开发;重构支持简化代码更新。通过定义公共接口确保一致性,用TypeScript编写微前端以保证质量。集成到构建流程确保顺利构建打包。在微前端场景中,TypeScript是强有力的语言选择。
30 2
|
25天前
|
前端开发 JavaScript API
Vue.js:渐进式JavaScript框架-前端开发
Vue.js:渐进式JavaScript框架-前端开发
24 3
|
6天前
|
前端开发 JavaScript
阿里云验证码2.0 验证时报错 前端页面获取的验证参数有问题,动态JS加载失败,请问怎么解决啊?急,急,急。
用户反馈校验时遇到错误,日志显示验证码参数获取异常。采用无痕验证,失败后,返回`{captchaResult:false,bizResult:false}`,未触发滑块二次验证。