浅拷贝for...in..
Object.assign()方法浅拷贝
1.待复制的属性必须是可枚举
2.待复制的属性必须是自有属性,不能继承自原型链
3.Object..assign(O进行的是浅拷贝--只遍历第-一级对象属性
4.Object..assign(0方法是ES6(ES2015)中新增的方法
使用扩展合并运算符...进行浅拷贝
回调函数
是一个函数,作为参数传给另一个函数,回调函数是在传给的函数内部被执行调用。
作用:1功能分化
2插槽特性
3滞后性
4可以循环
回调函数如果变成死循环不会卡死,会导致堆栈上限溢出,然后暂停报错
递归
不满足条件跳出函数,满足条件继续执行递归。如果变成死循环会不断产生副本导致堆栈溢出然后报错
函数中最后一句是执行自己调用递归,这种递归叫做尾递归,速度快。
递归尽量不要完成循环的事情,没有while for 快。而是使用递归完成深度遍历。
深拷贝
只嵌套对象时
嵌套对象和数组
```` // 原始数据
const o1 = {
name: "Jack",
age: 18,
info: {
height: 180,
weight: 180,
desc: {
message: "今天天气很好",
},
},
address: {
city: "北京",
},
hobby: ["吃饭", "睡觉"],
};
// 递归实现
function deepCopy(o1, o2 = {}) {
// 需要拿到你要拷贝的数据
for (let k in o1) {
// 判断值的数据类型
// 判断是不是对象
if (
Object.prototype.toString.call(o1[k]) ===
"[object Object]"
) {
// 代码能执行到这里 说明一定是对象
// 默认传递一个新对象
o2[k] = deepCopy(o1[k]);
// 递归实现
} else if (
Object.prototype.toString.call(o1[k]) ===
"[object Array]"
) {
// 代码能执行到这 说明一定是数组
// 传递一个新数组
o2[k] = deepCopy(o1[k], []);
// 递归实现
} else {
o2[k] = o1[k];
}
}
return o2;
}
var o2 = deepCopy(o1);
o1.info.desc.message = "我也知道";
o1.hobby[0] = "打豆豆";
console.log("o1:", o1, "o2:", o2);
使用json方法
封装任何类型都可以嵌套的
function cloneDeep(source, target) {
if (target === undefined) {
switch (true) {
case source instanceof Node:
target = source.cloneNode(true);
break;
case source.constructor.__proto__.name === 'TypedArray':
case source instanceof RegExp:
case source instanceof Date:
case source instanceof Set:
case source instanceof Map:
target = new source.constructor(source);
break;
default:
target = new source.constructor();
}
}
var names = Reflect.ownKeys(source);
for (var i = 0; i < names.length; i++) {
var key = names[i];
var desc = Object.getOwnPropertyDescriptor(source, key);
// console.log(typeof desc.value)
if (typeof desc.value === 'object' && desc.value !== null) {
// 引用类型
Object.defineProperty(target, key, {
configurable: desc.configurable,
writable: desc.writable,
enumerable: desc.enumerable,
value: cloneDeep(desc.value),
});
} else {
// 非引用类型
Object.defineProperty(target, key, desc);
}
}
return target;
}