深浅复制主要是针对于js的引用数据类型的,因为他们不只一层,并且修改一个变量是不希望修改到另外一个变量。
概念:
浅复制:只复制指向某个对象的指针,新旧对象共享一块内存,修改新对象会改到原对象上。
深复制:不共享内存,修改新对象不会改到原对象上。
实现:
浅复制实现:
js 简单的赋值操作一般实现的都是浅复制。
深复制实现的七种方法:
1. 手动复制:
var obj1 = {"name":"baibai", "age":"18"};
var obj2 = {"name":obj1.name, "age":obj1.age};
评价:需要手动一个一个的复制,比较麻烦,并且如果对象里还有对象就不可用了。
2. Object.assign方法:
Object.assign()是ES6的新函数,若对象多层则实现的是浅拷贝,拷贝的是对象的属性的引用,可进行一层的深复制。
var obj1 = {"name":"baibai", "age":"18"};
var obj2 = Object.assign({},obj1); //
3. JSON.stringify()和JSON.parse()
使用JSON.stringify()把对象转成字符串,而JSON.parse()再把字符串转成新对象即完成了复制。
var obj1 = {"name":"baibai", "age":"18"};
var obj2 = JSON.parse(JSON.stringify(obj1));
评价:深复制之后不管之前的变量是什么类型,都会变成Object,只有可以转成JSON格式的对象可使用这个方法,正则(RegExp)对象和function对象不可。
4. 递归复制
function deepClone(initalObj , finalObj){
var obj = finalObj || {};
for(var i in initalObj){
var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况,应该在遍历的时候判断是否相互引用对象,如果是则退出循环
if(prop === obj){
continue;
}
if(typeof prop === 'object'){
obj[i] = (prop.constructor === Array) ? [] : {};
arguments.callee(prop , obj[i]);
}else{
obj[i] = prop;
}
}
return obj;
}
var str = {};
var obj = { a: { a: "hello", b: 123}};
deepClone(obj, str);
console.log(str);
deepClone(被复制的对象,所要复制的对象);
5. Object.create()
直接使用
var obj1 = {"name":"baibai", "age":"18"};
var obj2 = Object.create(obj1)
Object.create()
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
6. jQuery的$.extend
var obj1 = {"name":"baibai", "age":"18"};
var obj2 = $.extend(true,{},obj1); //第一个参数为是否进行深拷贝,第二个参数是目标对象,第二个参数是被复制对象
obj2.name = "xiaobai";
console.log(obj1);
console.log(obj2);
评价:需要引进jQuery才可使用
7. lodash函数库
var _ = require('lodash');
var obj1 = {"name":"baibai", "age":"18"};
var obj2 = _.cloneDeep(obj1);
评价:需要进入lodash函数库