函数递归的三种方式

92 阅读2分钟

什么时候用递归:多层数据嵌套的时候

什么时候不建议使用递归:父级和子级有相同项时,执行单个删除操作(会将父级子级的元素一起删除),添加标记后删除的也是先匹配到的数据,而非我们希望的

方式一

function fn(num) {
    num += 10
    if (num < 100)  return fn(num)
    return num
}
fn(10)

方式二(严格模式下禁用)

function fn(num) {
    num+=5
    if (num < 100) return arguments.callee(num)
    return num
}
fn(10)

方式三(多此一举)

const bar = function fn(num){
    num+=5
    if (num < 100) return bar(num)
    return num
}
bar(10)

DEMO - 将jsonDate2的数据合并到jsonDate

// 递归多层数据处理
const jsonDate = [{
  name: '级别一',
  leavel: 1,
  children: [
    { name: '级别二-1', leavel: 2 },
    { 
      name: '级别二-2', 
      leavel: 2,
      children: [
        { name: '级别二-3', leavel: 3 },
      ]
    }
  ]
}]

const jsonDate2 = [{
  name: '级别一',
  path: './formatDate',
  fn: '日期格式化',
  children: [
    { name: '级别二-1', path: '/22222222', fn: '测试级别二有子集' },
    { 
      name: '级别二-2', 
      path: '/33333333',
      fn: '测试级别二有子集',
      children: [
        { name: '级别二-3', path: '/4444444', fn: '测试级别三' },
      ]
    }
  ]
}]

function recursion(data1, data2) {
  for(let i=0; i<data1.length;i++) {
    let item = data1[i]
    let item2 = data2[i]
    item.fn = item2.fn
    item.path = item2.path
    if (item.name === item2.name) {
      if (item.children) {
        return recursion(item.children, item2.children)
      }
    }
  }
  return data1
}
recursion(jsonDate, jsonDate2)

删除操作demo

// 这里我们删除第一层page为'/page2'的数据
const JSONData = [
    {
        path: '/page1', 
        children: [
            {page: '/page2'},
            {page: '/page3'}
        ]
    },
    {
        path: '/page2', 
        children: [
            {page: '/page2'},
            {page: '/page3'}
        ]
    }
]
// 递归删除方法,不加标记会删除所有匹配项
let sign = true
function recursion(data, delItem) { 
    for(let i=0; i<data.length;i++) { 
        if (data[i].path === delItem.path) {
            data.splice(i, 1)
            sign = false
        }
        if (data[i].children && sign) { 
            recursion(data[i].children, delItem) 
        } 
    }
} 
recursion(JSONData,{page: '/page2'})
/**
    执行完成后JSONData为以下数据,删除了第一层第一条的第二层path匹配的数据,但我们希望删除的是第一层的第二条
    [
        {
            path: '/page1', 
            children: [
                {page: '/page3'}
            ]
        },
        {
            path: '/page2', 
            children: [
                {page: '/page2'},
                {page: '/page3'}
            ]
        }
    ]

    如果不加标记则最终结果为
    [
        {
            path: '/page1', 
            children: [
                {page: '/page3'}
            ]
        }
    ]

*/