介绍

递归是解决问题的一种方法,它是能够自己调用自己的函数或者方法,必须要有终止条件。

调用栈大小

每个浏览器都有一个最大调用栈大小,当递归层级过深的时候,因为在递归的过程中会一直把临时变量封装为栈压入内存栈,如果一直压入,就会导致溢出导致服务崩溃。
每个浏览器都有自己的上限,代码如下:
结论:在函数调用15709次后,超出最大调用栈,内存溢出。所以在写递归函数时,一定要有终止条件。

  1. var i = 0;
  2. function recursiveFn() {
  3. i++;
  4. recursiveFn();
  5. }
  6. try {
  7. recursiveFn();
  8. } catch (ex) {
  9. console.log('i = ' + i + ' error: ' + ex);
  10. }
  11. //结果
  12. i = 15709 error: RangeError: Maximum call stack size exceeded

斐波那契数列

  • 1和2的斐波那契数是 1;
  • nn>2)的斐波那契数是(n1)的斐波那契数加上(n2)的斐波那契数。
    1. function fibonacci(num) {
    2. if (num === 1 || num === 2) {
    3. return 1;
    4. }
    5. return fibonacci(num - 1) + fibonacci(num - 2);
    6. }

优点

代码量少,易于理解

简单案例

使用递归实现阶乘函数

  1. function fact(num){
  2. if (num<=1){
  3. return 1;
  4. }else{
  5. return num * arguments.callee(num-1); //arguments.callee指向正在执行的函数
  6. }
  7. }
  8. fact(4); //结果为24.

场景1

简单的递归组件

  1. <template>
  2. <div class="list-detail">
  3. <list :list="list"></list>
  4. </div>
  5. </template>
  6. <script>
  7. import List from "./components/List";
  8. export default {
  9. name: "Parent",
  10. components: { List },
  11. data() {
  12. return {
  13. list: [{
  14. name: "经济",
  15. children: [{
  16. name: "如家",
  17. children: [{
  18. name: "上江路-如家"
  19. },
  20. {
  21. name: "望江路-如家"
  22. }]
  23. },{
  24. name: "7天",
  25. children: [{
  26. name: "长江路-7天"
  27. },
  28. {
  29. name: "望江路-7天"
  30. }]
  31. }]
  32. }]
  33. }
  34. }
  35. }
  36. </script>

List组件

  1. <template>
  2. <div>
  3. <div class="list-item" v-for="(item, index) in list" :key="index">
  4. <div class="item-name">
  5. <span>{{item.name}}</span>
  6. </div>
  7. <div v-if="item.children" class="children-item">
  8. <list :list="item.children"></list>
  9. </div>
  10. </div>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. name: "List",
  16. props: {
  17. list: Array
  18. }
  19. };
  20. </script>

场景2

条件:将扁平数组转换为树结构

  1. const a = [[1,2,3],['a','b','c'],['A','B','C']];
  2. [
  3. {
  4. label: '1',
  5. children:
  6. [
  7. { label: 'a',
  8. children:[
  9. {
  10. label:'A'
  11. }
  12. ]
  13. }
  14. ]
  15. },
  16. {
  17. label: '2',
  18. children:
  19. [
  20. { label: 'b',
  21. children:[
  22. {
  23. label:'B'
  24. }
  25. ]
  26. }
  27. ]
  28. },
  29. {
  30. label: '3',
  31. children:
  32. [
  33. { label: 'c',
  34. children:[
  35. {
  36. label:'C'
  37. }
  38. ]
  39. }
  40. ]
  41. }
  42. ]

代码实现

  1. function Fn (a) {
  2. let res = []
  3. for (let i = 0; i < a[0].length; i += 1) {
  4. const obj = {}
  5. let el = obj
  6. for (let j = 0; j < a.length; j += 1) {
  7. if (j === 0) {
  8. el.label = a[j][i]
  9. el.children = []
  10. } else {
  11. el.children.push({
  12. label: a[j][i],
  13. children: []
  14. })
  15. el = el.children[0]
  16. }
  17. }
  18. res.push(obj)
  19. }
  20. }

场景3

后面在vue深入学习时,会编写详细的案例…