手撕递归(原理:闭包)(求和;斐波拉契数列;爬楼梯;深拷贝;递归组件)

递归的实现原理,几个常见的递归

递归算法:

​ 递归现象:函数将自身内部的变量作为参数传递给自身的调用,并且将自身的调用结果返回出去
​ 递归实际利用的是闭包的原理

闭包原理:
函数执行的时候会开辟一个执行栈,在函数执行完以后就会进行内存释放,包括函数内部的变量,而函数return出的一个函数对函数内部变量进行引用的时候,函数内部变量就被保存在return出的函数当中,而无法在函数执行完以后进行内存释放。

递归关键的两个要素:
1.结束递归判断条件
2.运算表达式
注意:
1.由于递归中一般n是最大值,n逐渐减小,所以判断条件一般会和 1 有关
2.判断条件一定要在运算表达式的前面,否则递归不会停止

案例 1: 求和

function sum(n) {
    
    
  if (n == 1) return 1
  return sum(n - 1) + n
}

案例 2: 斐波拉契数列

0,1,1,2,3,5,8,13,21,34,55,89…求第 n 项

// 递归方法
function fib(n) {
    
    
  if (n === 1 || n === 2) return n - 1
  return fib(n - 1) + fib(n - 2)
}
console.log(fib(10)) // 34
//非递归方法 //
function fib(n) {
    
    
  let a = 0
  let b = 1
  let c = a + b
  for (let i = 3; i < n; i++) {
    
    
    a = b
    b = c
    c = a + b
  }
  return c
}
console.log(fib(10)) // 34

案例 3: 爬楼梯

JS 递归 假如楼梯有 n 个台阶,每次可以走 1 个或 2 个台阶,请问走完这 n 个台阶有几种走法

function climbStairs(n) {
    
    
  if (n == 1) return 1
  if (n == 2) return 2
  return climbStairs(n - 1) + climbStairs(n - 2)
}

案例 4: 深拷贝

原理: clone(o) = new Object; 返回一个对象

function clone(o) {
    
    
  var temp = {
    
    }
  for (var key in o) {
    
    
    if (typeof o[key] == 'object') {
    
    
      temp[key] = clone(o[key])
    } else {
    
    
      temp[key] = o[key]
    }
  }
  return temp
}

案例 5:递归组件

  • 递归组件: 组件在它的模板内可以递归的调用自己,只要给组件设置 name 组件就可以了。
  • 不过需要注意的是,必须给一个条件来限制数量,否则会抛出错误: max stack size exceeded
  • 组件递归用来开发一些具体有未知层级关系的独立组件。比如:联级选择器和树形控件
<template>
  <div v-for="(item,index) in treeArr"> {
    
    {
    
    index}} <br/>
      <tree :item="item.arr" v-if="item.flag"></tree>
  </div>
</template>
<script>
export default {
    
    
  // 必须定义name,组件内部才能递归调用
  name: 'tree',
  data(){
    
    
    return {
    
    }
  },
  // 接收外部传入的值
  props: {
    
    
     item: {
    
    
      type:Array,
      default: ()=>[]
    }
  }
}
</script>

猜你喜欢

转载自blog.csdn.net/2301_76866366/article/details/131668637