说到递归,一直以来在工作中的确是有用到过,但并没有进行总结和进一步的理解,看到前人做过很多的总结,这里也自己整理记录一下,方便日后翻阅;
1、什么是递归?
在js中,我们写页面,写函数,写方法的时候用到过,简单来说,递归就是在一个函数的方法里 调用 自己;
2、怎么去写递归?
首先设置终止条件,满足条件则返回;否则,重复调用自身;举个粒子:
a、实现 1234n的值?
var funVal=function(n){
//设置终止条件
if(n<=1) return 1;
//否则重复调用自身
return funVal(n-1) * n
}
b、求第n项的值,斐波那契数列:1,1,2,3,5,8,13...第n项值是多少?
很显然从第3项起是前面两项的数值的和,那么终止条件就有了,如果n==1 || n==2 返回 1;
var fibo = function(n){
// 如果是第一项或者第二项,则直接返回1
if(n==1||n==2) return 1;
//否则的话,返回前两项的和
return fibo(n-1)+fibo(n-2)
}
console.log(fibo(5))
3、工作中用到递归的时候
a、深拷贝取值
当我们对象是json格式的对象时,没有特殊函数的时候,可以用到递归的思想来取到我们想要的数据:
**数据格式:**
copydata:[
'abc',
{
name:zx,
content:{
c:2
}
},
{
arr:['3',4,'5']
}
],
***方法:***
//判断是否是对象
isObject(obj){
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
},
//用递归的方式进行深拷贝
deepClone(obj){
if(!this.isObject(obj)) return obj; //判断是否是对象或者是数组,如果不是则返回原始值
var result = new obj.constructor(); //创建一个对象返回;巧妙避免对当前数据是数组还是对象的判断
for(var i in obj){
if(obj.hasOwnProperty(i)){
result[i] = this.deepClone(obj[i]);
}
}
return result;
},
***调用:***
let obj = this.deepClone(this.copydata)
console.log("copyobj======",obj)
b、遍历元素所有子节点
dom 结构:
<template>
<div class="hello" id="hello">
<div>递归调用</div>
<p>这是文字。。。。。</p>
</div>
</template>
方法:
//递归遍历元素的所有子节点 给每个元素节点添加'data-index'属性
/**
* @param {节点或元素} root 要递归的节点或元素
* @param {function} callback 每一次遍历的回调函数
*
*/
getChildNodes(root,callback){
// 判断是否存在子元素
if(root && root.children && root.children.length){
//将子元素转换成可遍历的数组
Array.from(root.children).forEach(node=>{
callback && typeof callback === 'function' && callback(node);
//递归子元素,重复上面操作
this.getChildNodes(node,callback)
})
}
},
调用:
const root = document.getElementById('hello');
this.getChildNodes(root,function(node){
console.log(node,"node=====")
node.setAttribute('data-index','123')
})
image.png
c、遍历树形结构
数据:
tree:{
name: '电脑',
children: [
{
name: 'F盘',
children: [
{
name: '照片',
children: []
},
{
name: '文件',
children: [
{
name: '工作文件',
children: [
{
name: '报告',
children: []
}
]
}
]
}
]
},
{
name: 'E盘',
children: [
{
name: '视频',
children: [
{
name: 'js教程',
children: []
}
]
}
]
}
]
}
方法:采用深度优先原则
// 树形结构递归 遍历树形结构深度优先原则:就是顺着一个节点延伸下去,先遍历它的第一个子节点,
// 然后是第一个孙节点,然后重孙节点,直到没有子节点为止。即先纵深遍历完之后在遍历同级的其他节点。
deepTraversal(root,cb){
let that = this;
if(!root) return;
cb && typeof cb === 'function' && cb(root);
if(root.children && root.children.length){
var i = 0,node;
for(;node=root.children[i++];){
that.deepTraversal(node,cb);
}
}
}
调用:
//遍历树形结构
this.deepTraversal(this.tree,function(node){
console.log("打印名字=====",node.name)
})
image.png
网友评论