前言
https://www.cnblogs.com/panrui1994/p/9378696.html
Angular 在进行对象的赋值的时候,假如你直接使用 “=” 赋值,那么当这个你这个赋值后的对象里的属性改变的时候,源对象也会相应的改变。所以如果不想源对象的属性也改变,这就需要进行深拷贝了,下面介绍四种比较方便的深拷贝方法
第一种JSON.parse(JSON.stringify(obj))
缺点:对象必须遵从JSON格式
var obj1 = {
name:'张三'
}
//obj1 是源对象
var obj2 = JSON.parse(JSON.stringify(obj1));
//obj2 是拷贝后的对象
obj2.name = '李四';
console.log(obj1); //{name:张三}
console.log(obj1 === obj2); //false
// 缺点:对象必须遵从JSON格式
var obj1 = {
a: '1',
b: '2',
c: function func() {}
};
var obj4 = JSON.parse(JSON.stringify(obj1));
console.log(obj4) //{ a: '1', b: '2' }
第二种Object.assign(target, …sources)
缺点:IE下报错,不存在次方法
// 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象
// 复制
let c = Object.assign({}, { a: '1' });
console.log(c); // { a: '1' };
//合并
let a = {};
let b = Object.assign(a, { a: '1' }, { b: '2' }, { c: '3' } );
console.log(b) // { a: '1', b: '2', c: '3' };
//如果对象本身存在的属性会更新,不存在的属性会增加
var a = {a:'1'};
var b = {a:'2', b:1};
var c = Object.assign(a, b);
console.log(a); //{a:'2',b:'1'}
console.log(b);//{a:'2',b:'1'}
console.log(c);//{a:'2',b:'1'}
第三种迭代递归法 for…in
缺点: func、date、reg 和 err 并没有复制成功,因为它们有特殊的构造函数。
//拷贝对象
var test = {
num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: {
name: '我是一个对象',
id: 1
},
arr: [0, 1, 2],
func: function() {
console.log('我是一个函数')
},
date: new Date(0),
reg: new RegExp('/我是一个正则/ig'),
err: new Error('我是一个错误')
}
function deepClone(obj) {
//判断传进来的是对象还是数组
var isArray = Array.isArray(obj)
var cloneObj = isArray ? [] : {}
//通过for...in来拷贝
for (let key in obj) {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
}
return cloneObj
}
console.log(deepClone(test))
第四种迭代递归法 Reflect(跟第三种类似效果也一样)
缺点: func、date、reg 和 err 并没有复制成功,因为它们有特殊的构造函数。
//拷贝对象
var test = {
num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: {
name: '我是一个对象',
id: 1
},
arr: [0, 1, 2],
func: function() {
console.log('我是一个函数')
},
date: new Date(0),
reg: new RegExp('/我是一个正则/ig'),
err: new Error('我是一个错误')
}
function deepClone(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一个对象!')
}
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(cloneObj).forEach(key => {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return cloneObj
}
console.log(deepClone(test))