函数内部不断调用自身。递归函数的使用要注意函数终止条件避免死循环(一般都要写一个结束的条件);
//在递归的过程中会出错
// Maximum call stack size exceeded
// 内存溢出:超过了最大的堆栈大小
递归应用场景: 深拷贝 菜单树 遍历 DOM 树
递归两个要素
1.递归的边界——找到出口,在什么情况下跳出递归
2.递归的逻辑——找到入口,什么情况下重复调用自己,调用自己做什么
求 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 1
return fib(n - 2) + fib(n - 1)
}
console.log(fib(3))
var oldObj = {
name: 'zs',
age: 18,
dog: {
name: 'xx',
age: 2
},
friend: ['lisi', 'ww']
};
function deepCopy(oldObj) {
let newObj = Array.isArray(oldObj) ? [] : {};
for (var key in oldObj) {
var item = oldObj[key];
if (item && typeof (item) === "object") { // 对象和数组
newObj[key] = deepCopy(item)
} else { //基本类型的拷贝
newObj[key] = item;
}
}
return newObj
}
console.log(deepCopy(oldObj))
let data = [
{name:'分类1',children:[
{name:'分类1-1',children:[
{name:'分类1-1-1'}
]},
{name:'分类1-2'}
]},
{name:'分类2',children:[
{name:'分类2-1'}
]},
{name:'分类3'}
];
let tree = document.getElementById('tree');
createTree(tree, data)
function createTree(element, data){
let ul = document.createElement('ul');
element.appendChild(ul);
for(let i = 0; i < data.length; i++){
let li = document.createElement('li');
ul.appendChild(li);
li.innerText = data[i].name;
if(data[i].children && data[i].children.length > 0){
createTree(li, data[i].children)
}
}
}
//遍历li元素并添加点击事件
function loadTree(parent, callback){
for(var i = 0; i < parent.children.length; i++){
var child = parent.children[i];
if(callback){
callback(child);
}
loadTree(child);
}
}
var ul = document.querySelector('ul');
loadTree(ul, function(element){
element.onclick = function(){
console.log(this.innerText)
}
})