浅度拷贝:
复制一层对象的属性,并不包括对象里面的为引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变。
如:
var obj = {
name: '小明',
age: 12,
car: ['宝马', '奔驰', '兰博基尼']
}
var obj1 = obj;
console.log(obj1.name);
//用函数封装,浅拷贝
var obj2 = {};
function extend(a, b) {
for (var key in a) {
b[key] = a[key]
}
}
//调用函数
extend(obj, obj2);
console.log(obj2.name, obj2.age, obj2.car);
深拷贝:
浅拷贝只在根属性上在堆内存中创建了一个新的的对象,复制了基本类型的值,但是复杂数据类型也就是对象则是拷贝相同的地址。
而深拷贝则是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。
实现: 浅拷贝+递归
这里的递归:
在程序中函数直接或间接调用自己,然后跳出结构,返回结果
- 递归的步骤(技巧)
- 假设递归函数已经写好
- 寻找递推关系
- 将递推关系的结构转换为递归体
- 将临界条件加入到递归体中
var i=0
function f1() {
i++;
if (i<6){
f1();
}
console.log('hello');
}
f1();//输出6次"hello"
我们再回到深拷贝这个话题中
JSON.stringify()是目前开发过程中最常用的深拷贝方式,原理是把一个对象序列化成为一个JSON字符串,将对象的内容转换成字符串的形式再保存在内存中,再用JSON.parse()反序列化将JSON字符串变成一个新的对象。如:
var obj = {
name: '小明',
age: 12,
car: ['宝马', '奔驰', '兰博基尼'],
dog: {
name: '小白',
color: '黑色',
}
}
var obj1 = {};
//完成obj向obj1 的 深拷贝
function extend(a, b) {
for (var key in a) {
//获取a属性值
var item = a[key];
//判断数据类型: 简单数据----直接复制
// 数组和对象---开辟空间,一个个复制
if (Array.isArray(item)) {
//如果是数组---先在b对象中添加一个新属性,并且这个属性值是一个数组
b[key] = [];
extend(item, b[key])
} else if (item instanceof Object) {
//如果是对象---先在b的属性中开辟空间,再复制item所有属性和方法
b[key] = {}
extend(item, b[key]);//item是a[key]下的对象,再复制给b[key]
}
b[key] = a[key];
}
}
extend(obj, obj1);
console.log(obj1);