Js高级------递归
在程序中函数直接或间接调用自己
1. 直接调用自己
2. 间接调用自己
· 跳出结构,有了跳出才有结果
· 递归的调用,最终还是要转换为自己这个函数
1. 如果有个函数foo,如果他是递归函数,到最后问题还是转换为函数foo的形式
2. 递归的思想就是将一个未知问题转换为一个已解决的问题来实现
function foo(){
...foo(...)...
}
1. 假设递归函数已经写好
2. 寻找递推关系
3. 将递推关系的结构转换为递归体
4. 将临界条件加入到递归体中
1.求 1,3,5,7,9,...第n项的结果和前n项和,序号从0开始
function foo(n){
if(n == 1){
Return 1;
}else{
return foo(n) = sum(n-1)+2;
}
}
2. 求8的阶乘
1.求 1,3,5,7,9,...第n项的结果和前n项和,序号从0开始
function foo(n){
if(n == 1){
return 1;
}else{
return foo(n) = sum(n-1)+2;
}
}
比如:s=“abcdef”,逆序后变为“fedcba”
深拷贝,使用递归方式
概念:1. 如果拷贝的时候, 将数据的所有引用结构都拷贝一份, 那么数据在内存中独立就是深拷贝(内存隔离,完全独立)
2. 如果拷贝的时候, 只针对当前对象的属性进行拷贝, 而属性是引用类型这个不考虑, 那么就是浅拷贝
3. 拷贝: 复制一份. 指将对象数据复制.
4. 在讨论深拷与浅拷的时候一定要保证对象的属性也是引用类型.
实现方法:
5. 如果要实现深拷贝那么就需要考虑将对象的属性, 与属性的属性,都拷贝过来
6. 分析(2个参数,简单实现)
1. 假设已经实现 clone ( o1, o2),将对象 o2 的成员拷贝一份交给 o1
2. 递推关系
* 混合方法,将 o2 的成员拷贝到 o1 中
```
function clone( o1, o2){
for(var key in o2){
o1[key] = o2[key];
}
}
```
* 假设方法已经实现,如果 o2[key] 是对象
* 继续使用这个方法
* 需要考虑 o2[key] 是引用类型,再一次使用clone函数
* 如果 o2[key] 不是引用类型,那么直接赋值
3. 临界条件
* 因为是 for in 循环,没有成员遍历时,自动结束
4. 递归函数
function clone(o1,o2){
for(var key in o2){
if(typeof o2[key] == 'object'){
o1[key] = {};
clone(o1[key],o2[key])
}else{
o1[key] = o2[key];
}
}
}复杂实现(一个参数)
原理: 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;
}
# 使用递归实现 getElementsByClassName
html结构:
分析
1. 实现一个方法byClass()需要的参数是:
node: 在某个节点上寻找元素
className: 需要寻找的className
arr: 找到的元素存储到这个数组中
2. 遍历 node 的子节点,
3. 查看这个子节点是否还有子节点,如果没有直接存储到数组中,如果有就继续递归
var arr = [];function byClass(node, className, arr){
//得到传入节点的所有子节点
var lists = node.childNodes;
for(var i = 0;i< lists.length;i++){
//判断是否有相同className元素
if(arr[i],className == className){
arr.push(arr[i]);
}
//判断子节点是否还有子节点
if(arr[i].childNodes.length > 0){
byClass(arr[i],className,arr);
}
}
}