javascript函数式编程08-高阶函数(递归函数)

314 阅读2分钟

这是我参与更文挑战的第8天,活动详情查看: 更文挑战

紧跟上一篇 ,这一篇主要了解高阶函数(递归函数)

什么是递归?
  • 递归是一项非常重要的编程技巧,函数通过它调用其本身。 —msdn 文档介绍
  • 函数自己调用自己本身,或者在自己函数调用的下级函数中调用自己。
  • 举个例子: 阶乘
function factorial(i) {
  if (i === 1) return i;
  return i * factorial(i - 1);
}
console.log(factorial(5)); // 5*4*3*2*1

分几个步骤

  1. 声明一个函数 factorial,接受一个参数 i。 2.判断 i 是否等于 1,如果等于 1 则直接返回 i。 3.如果 i 不等于 1,则返回 i * factorial(i - 1),再次调用函数本身。(如此如果严格可以判断 i 是否大于等于 0)然后函数就会重复 2 - 3 两个步骤,直至 i 减到 1 为止。
递归函数的步骤
  1. 假设递归函数已经写好
  2. 寻找递推关系
  3. 将递推关系的结构转换为递归体
  4. 将临界条件加入到递归体中
经典案例
  • 求和:求 1-100 的和
function sum(n) {
  if (n == 1) return 1
  return sum(n - 1) + n
}
  • 斐波拉契数列: 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
  • 爬楼梯: 假如楼梯有 n 个台阶,每次可以走 1 个或 2 个台阶,请问走完这 n 个台阶有几种走法
function climbStairs(n) {
  if (n == 1) return 1
  if (n == 2) return 2
  return climbStairs(n - 1) + climbStairs(n - 2)
}
  • 深拷贝: 原理: 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
}
  • 递归组件
    • 递归组件: 组件在它的模板内可以递归的调用自己,只要给组件设置 name 组件就可以了。
    • 不过需要注意的是,必须给一个条件来限制数量,否则会抛出错误: max stack size exceeded
    • 组件递归用来开发一些具体有未知层级关系的独立组件。比如:联级选择器和树形控件
<!-以vue为例-->
<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>
递归函数调用方法
  • 通过函数自身名字递归调用
function sum(num){
  if(num<=1){
    return 1;
  }else{
    return num+sum(num-1);
  }
}

console.log(sum(2));//3
  • 通过arguments.callee调用函数自身
function sum(num){
  if(num<=1){
    return 1;
  }else{
    return num+arguments.callee(num-1);
  }
}
console.log(sum(3));//6

var sumAnother=sum;
console.log(sumAnother(8));//36

sum=null;
console.log(sumAnother(5));//15
  • 通过函数命名表达式来实现arguments.callee效果
var sum=(function(){
    'use strict'
    return  function fun(num){
        if(num<=1){
            return 1;
        }else{
            return num+fun(num-1);
        }
    }
})()
console.log(sum(5));//15

var sumAnother=sum;
console.log(sumAnother(5));//15

sum=null;
console.log(sumAnother(5));//15
  • 以上所述是给大家介绍的详解JS的递归函数,希望对大家有所帮助