深拷贝的几种方式
1.使用递归深拷贝
var obj = {
name:'张三',
age:20,
card:['11','22',33],
wife:{
name:'李四',
son:{
name:'张六'
}
},
say:function(){
var a=3,b=5;
sum = a+b;
return sum;
}
}
//调用封装的深拷贝函数
var obj1 = deepClone(obj);
//修改一个拷贝过来的对象,看原来对象里边数据是否改变
obj1.wife.name = '小明';
console.log(obj);
console.log(obj1);
console.log(obj.say());
console.log(obj1.say());
//封装函数拷贝
function deepClone(origin){
//哦按段需拷贝的数据是数组还是对象
let target = Array.isArray(origin)?[]:{};
//如果需要拷贝的数据存在,并且是引用类型
if(origin && typeof origin === "object"){
//循环遍历
for(var k in origin){
//该属性有可能是原型上的,所以要判断该属性是否是本身的
if(origin.hasOwnProperty(k)){
//判断origin是否为对象,如果是,递归赋值
if(origin[k] && typeof origin[k] === 'object'){
target[k] = deepClone(origin[k]);
}else{
//如果不是,简单复制
target[k] = origin[k];
}
}
}
}
return target;
}
拷贝成功
2.第二种Object.assign() 加递归深拷贝
Object.assign
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
Object.assign
方法的第一个参数是目标对象,后面的参数都是源对象。
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
function deepClone(origin) {
let target = Array.isArray(origin) ? [] : {};
// let target = {};
if (origin && typeof origin === 'object') {
for (let k in origin) {
//判断是引用值,但是不是数组类型的
if (origin[k] && typeof (origin[k]) == "object") {
let obj = {};
obj[k] = deepClone(origin[k]);
//把原始对象拷贝给target,然后返回出去
Object.assign(target, obj);
} else {
let obj = {};
obj[k] = origin[k];
//把原始对象拷贝给target,然后返回出去
Object.assign(target, obj);
}
}
}
return target;
}
var obj = {
name: '张三',
age: 20,
card: ['11', '22', 33],
wife: {
name: '李四',
son: {
name: '张六'
},
aa:[{a:1},{b:2},{c:3}]
},
say: function () {
var a = 3, b = 5;
sum = a + b;
return sum;
}
}
var obj1 = deepClone(obj);
obj1.wife.name = '小明';
console.log(obj);
console.log(obj1);
console.log(obj.say());
console.log(obj1.say());
结果如下
3.第三种最简单的深拷贝
使用JSON.stringify()把对象转换为json字符串,然后使用JSON.parse() 把json格式的字符串转换为对象,就是一个深拷贝
function deepClone(obj){
return JSON.parse(JSON.stringify(obj));
}
var obj = {
name:'张三',
age:20,
card:['11','22',33],
wife:{
name:'李四',
son:{
name:'张六'
}
}
}
var obj1 = deepClone(obj);
obj1.wife.name = '小明';
console.log(obj);
console.log(obj1);