递归
- 什么是递归
递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己, 这个函数就是递归函数 函数的递归,递归函数 递归:函数调用函数其本身 **注意:**递归函数的作用和循环效果一样,由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。
利用递归求1~n的任意一个数的阶乘
/* 3的阶乘==》3X2X1
6的阶乘==》6X5X4X3X2X1
9的阶乘==》9X8X7X6X5X4X3X2X1
利用递归求1~n的任意一个数的阶乘*/
function jC (n) {
nx(n-1)x(n-1-1)x(n-1-1-1)......1
if (n == 1) {
return 1;
}
// 我们要的是一个结果
return n * jC(n-1);
return 4 * jC(3);
return 4 * 3 * 2 * 1;
}
console.log( jC(4) );
/*利用递归求斐波那契数列
利用递归函数求斐波那契数列(兔子序列)
从第三个月开始生兔子
1、1、2、3、5、8、13、21...
第n个月有几对兔子*/
function fb (n) {
/* 递归点:前一个月 +前二的月的兔子
出口点:第一个月和第二个月是固定的都是1*/
if (n == 1 || n == 2) {
return 1;
}
return fb(n-1) + fb(n-2);
/* return fb(5) + fb(4);
return 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1;*/
}
console.log( fb(6) );
/* console.log( fb(8) );
console.log( fb(13) );*/
<script type="text/javascript">
var data = [
{
id : 1,
name : '家电',
goods : [
{
id : 11,
name : '冰箱',
goods : [
{
id : 111,
name : '海尔'
},{
id : 112,
name : '美的'
}
]
},{
id : 12,
name : '洗衣机 '
}
]
},
{
id : 2,
name : '服饰'
}
];
// var data = [{},{}];
// 写一个函数,根据给出得到id去能够获取指定的数据
// 获取数据
function getId (arr, id) {
// 定义一个变量
var obj = {};
// 遍历
arr.forEach(function (val, index) {
// val = { id : 1, name : '加点'}
if (val.id == id) {
obj = val;
} else if (val.goods && val.goods.length > 0) {
obj = getId(val.goods, id);
}
});
return obj;
}
console.log( getId(data,111) );
// id = 10086
深拷贝和浅拷贝
- 拷贝不能直接赋值,对象赋值的是地址
var obj = {
name : '张三丰',
age : 22
};
var newObj = obj;
console.log(newObj);
-
浅拷贝:
- 只拷贝最外面一层
var obj = { name : '张三丰', age : 22, // color : ['red','blue','yellow'], // message : {sex : '男',score : 99} }; var newObj = {}; Object.assign(newObj, obj); obj.name = '李寻欢'; console.log(obj, newObj); // 遍历 for ( key in obj ) { // obj有什么newObj就有什么 newObj[key] = obj[key]; } obj.name = '阿飞'; obj.message.sex = '女'; console.log(obj); console.log(newObj); // obj.name // obj有什么newObj就有什么 newObj.name = obj.name; newObj.age = obj.age; obj.name = '李寻欢'; console.log(obj); console.log(newObj); newObj = '张三丰'; </script>
深拷贝
var obj = {
name : '张三丰',
age : 22,
color : ['red','blue','yellow'],
message : {sex : '男',score : 99}
};
var newObj = {};
// 封装
function kaobei (newObj, obj) {
/* 要把obj拷贝给newObj
我们发现,obj[key]可能是数组,还能是对象,具有复杂数据
那么此时直接拷贝,又会变成复杂数据类型传递*/
for ( key in obj ) {
// newObj[key] = obj[key];
if ( obj[key] instanceof Array ) { /* obj[key]是数组,就在遍历
在遍历
newObj[key] = obj[key]*/
newObj[key] = [];
kaobei(newObj[key], obj[key]);
} else if ( obj[key] instanceof Object ) { // obj[key]是对象,就在遍历
// newObj[key] = obj[key]
newObj[key] = {};
kaobei(newObj[key], obj[key]);
} else {
newObj[key] = obj[key];
}
}
}
kaobei(newObj, obj);
// obj.name = 'aaa';
obj.message.sex = '女';
console.log(obj);
console.log(newObj);
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
首先深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。
-
浅拷贝:只拷贝最外面一层【Object.assign(newObj,obj)】
-
深拷贝:所有层都拷贝