浅拷贝:只拷贝数组或者对象的引用,无论在新的或者旧的数组或者对象中作了修改,两者都会发生变化,即两个指向的地址是同一块。
深拷贝:这种拷贝使两者分离,修改一个对象的属性,另外一个也不会有影响,即深拷贝会把所有东西重新复制一份放在另一个地方,两者指向的不是同一块地址。
1. JSON.stringify() &JSON.parse()
将JSON.stringify对象转换成字符串,然后通过JSON.parse将字符串转换成对象
var obj = {a:1, b:2, c:3}; var obj2 = JSON.parse(JSON.stringify(obj)); obj2.a = 2; console.log(obj.a); console.log(obj2.a);
上面的结果输出分别是:1和2
说明obj 和 obj2之间没有关系了,实现深拷贝
缺点:只能用于对象属性的深拷贝不能用于对象方法的拷贝
var arr = [function(){ console.log(a) }, { b: function(){ console.log(b) } }] var new_arr = JSON.parse(JSON.stringify(arr)); console.log(new_arr);
输出结果:
2. Object.assign(),可以实现对象属性和方法的深拷贝
实现对象属性的深拷贝
const object1 = { a: 1, b: 2, c: 3 }; const object2 = Object.assign({}, object1); object2.a = 2; console.log(object1); console.log(object2);
实现对象方法的深拷贝
const object1 = { a: 1, b: 2, c: function() {console.log('hello')} }; const object2 = Object.assign({}, object1); object2.c = function() { console.log('test'); } console.log(object1.c()); console.log(object2.c());
输出结果分别是:'hello'和'test'
以上两个方法都可以实现对象深拷贝,但是各自的使用是有限制的,可以根据需求使用。
3. 用js方法实现深拷贝
function deepClone(source, target) { var target = target || {}, toStr = Object.prototype.toString, // arrType = '[object Array]'; for(key in source) { if(typeof(source[key]) === 'object' && source[key] !== null) { if(toStr.call(source[key]) === arrType) { //判断一个对象是否是数组 target[key] = []; } else { target[key] = {}; } deepClone(source[key], target[key]); //对象或者数组中还有数组则用递归调用 } else { target[key] = source[key]; } } return target; } var sour = { a: '1', b: { aa: 1, bb: [1, 2], cc: { xx: 1, yy: [{a: 1}] } } }; var tar = deepClone(sour); tar.b.cc.xx = 2; tar.b.cc.yy.push({b:2}); console.log(tar); console.log(sour);