1:找规律
2:找出口
var data = [
{
name: "所有物品",
children: [
{
name: "水果",
children: [{name: "苹果", children: [{name: '青苹果'}, {name: '红苹果'}]}]
},
{
name: '主食',
children: [
{name: "米饭", children: [{name: '北方米饭'}, {name: '南方米饭'}]}
]
},
{
name: '生活用品',
children: [
{name: "电脑类", children: [{name: '安卓电脑'}, {name: '苹果电脑'}]},
{name: "工具类", children: [{name: "锄头"}, {name: "锤子"}]},
{name: "生活用品", children: [{name: "洗发水"}, {name: "沐浴露"}]}
]
}
]
}]
需要最后在页面上显示每一级的最后一个数据。
青苹果;红苹果;北方米饭;南方米饭;安卓电脑;苹果电脑;锄头;锤子;洗发水;沐浴露;
普通遍历的方法
var forFunction = function () {
var str = ""
data.forEach(function(row){
row.children.forEach(function(row){
row.children.forEach(function(row){
row.children.forEach(function(row){
str += (row.name + ";")
})
})
})
})
console.log(str)
}
forFunction()
//输出:青苹果;红苹果;北方米饭;南方米饭;联想电脑;苹果电脑;锄头;锤子;洗发水;沐浴露;
//可以看到,费劲半天写了4个forEach实现了要的效果,如果再加点别的什么逻辑,就很难弄了。这时候我们尝试用递归的思想实现:
递归遍历实现
var recursiveFunction = function(){
var str = ''
const getStr = function(list){
list.forEach(function(row){
if(row.children){
getStr(row.children)
}else {
str += row.name + ";"
}
})
}
getStr(data)
console.log(str)
}
recursiveFunction()
//输出:青苹果;红苹果;北方米饭;南方米饭;联想电脑;苹果电脑;锄头;锤子;洗发水;沐浴露;
//可以看到,递归的方式来实现的时候,我们只需要一个for循环,每次遍历接受到的数据,通过判断是否还有children,没有就代表是最后一级了,有就继续把children这个list传给函数继续遍历,最后就得到了我们想要的数据。
很明显,forEach的遍历的方式能实现多级的遍历,并且数据格式可以灵活一些,但是遍历的层级有限,而且对于未知层级的情况下,就无从下手了。 递归遍历,理论上,只要内存够用,你能实现任意层级的遍历,但缺点也很明显,没一个层级里面需要有固定的数据格式,否则无法遍历。
递归遍历轻松实现多个异步结果的依次输出
需要依次输出1,2,3,4,5,每个输出中间间隔1s。
//常规实现
var forTest = function () {
console.time("for时间")
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log('for循环输出:' + (i + 1))
if(i+ 1 === 5){
console.timeEnd("for时间")
}
}, 1000 * (i + 1))
}
}
forTest()
//用let当前作用域的特点实现了每隔1s输出,其实可以看出,是一起执行的,但是由于间隔时间不一样,导致结果是每隔一秒输出的。
//递归遍历实现
var recursiveTest = function(){
console.time("递归时间")
const test = function (i) {
setTimeout(function () {
i = i + 1
console.log('递归输出:' + i)
if(i < 5){
test(i)
}else {
console.timeEnd("递归时间")
}
}, 1000)
}
test(0)
}
recursiveTest()
//这里利用递归实现就很好理解了,在setTimeout里面输出了之后,再开始下一个1s的输出。
总结
1.很多时候可以用递归代替循环,可以理解为递归是一种特殊的循环,但通常情况下不推荐这样做。
2.递归一般是在函数里面把函数自己给调用一遍,通过每次调用改变条件,来结束循环。
3.递归在数据格式一致,在数据层级未知的情况下,比普通的遍历更有优势。
4.递归在异步的时候,更容易理解,且更容易实现,因为可以在异步的回调里面,调用自己来实现每次都能拿到异步的结果再进行其他操作。
5.递归实现的快速排序比普通遍历实现的排序效率更好。