拷贝(也称克隆),指的是我们对从服务器请求回来的数据,进行"复制",我们可以对副本进行修改等操作,不能影响到原来的数据,如果修改的数据不理想,可以在不向服务器从新发送请求的情况下,返回到原来的数据,
浅拷贝和深拷贝的区别是:浅拷贝只会拷贝对象最外部的一层,至于更深层次的对象,则依然是通过引用指向同一块堆内存.(意思是,拷贝之后的对象发生了变化,原对象也会发生变化);而深拷贝在一定程度上,解决了这个问题
浅拷贝
// 浅拷贝函数
function shallowClone(oldobj) {
const obj = { }; //const 常量
for ( let i in obj) {
obj [i] = oldobj [i];
}
return obj;
}
// 被克隆对象
const oldObj = {
a: 1,
b: [ 'e', 'f', 'g' ],
c: { h: { i: 2 } }
};
const newObj = shallowClone(oldObj);
console.log(newObj.c.h, oldObj.c.h); // { i: 2 } { i: 2 }
console.log(oldObj.c.h === newObj.c.h); // true
newObj.c.h.i = 'change';
console.log(newObj.c.h, oldObj.c.h); // { i: 'change' } { i: 'change' }
// 改变newobj的值,oldobj的值也会变(说明他们指向了同一段堆内存),这种效果并不是我们想要的,所以,出现了深拷贝
深拷贝
第一种方法--------深拷贝函数
```
//使用递归的方式实现数组、对象的深拷贝
function deepClone1(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone1(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
原文链接:https://blog.csdn.net/chentony123/article/details/81428803
```
var oldobj={
name:"apple",
price:28,
des:{a:{i:3}}
}
var newobj = deepCopy(oldobj);
console.log(newobj,oldobj); // { i : 3 },{ i : 3 }
newobj.des.a.i=7;
console.log(newobj,oldobj);// { i : 7 },{ i : 3 } //新对象的 i 值变了,原对象的 i 值并没有变
第二种方法------json.parse(),和json.stringify()方法
var oldobj={
name:"apple",
price:28,
des:{a:{i:3}}
}
var newobj = JSON.parse(JSON.stringify(oldobj));
console.log(newobj,oldobj); // { i : 3 },{ i : 3 }
newobj.des.a.i=7;
console.log(newobj,oldobj);// { i : 7 },{ i : 3 } //得到的效果是和深拷贝函数的效果一样
但是,深拷贝的两种方法,都只能解决普通的深拷贝问题,特殊的对象(函数,正则对象,构造函数,稀疏数组),这两种方法还解决不了.
functionPerson(name){
this.name=name;
}
var lili= new Person("lili")
function say(){
console.log("hi")
}
var oldobj= {
a:lili,
b:say,
c:new Array(1),
d:RegExp("abc","i")
}
var newobj= deepcopy(oldobj);
console.log(newobj.a,oldobj.a); //object , Person //构造函数的指向不一样
console.log(newobj.b,oldobj.b); //function , function 拷贝函数打印的效果是对的,json.parse方法不行,打印的新对象为空
console.log(newobj.c,oldobj.c); // { }, [ empty ]
console.log(newobj.d,oldobj.d); // { }, / abc / i
总结:一般情况下,深拷贝的两种方法就应经够用了,如果遇到处理特殊对象的问题,再具体问题具体分析吧.
```
// 深克隆
// 循环遍历每一个元素,判断是原始值还是引用值
// 如果是原始值,就直接赋值,如果是引用值,就再次判断是object,还是array
// 新建 [] || {} 再赋值
// 循环递归
function deepclone (orign,target){
var target = target || {}
var toStr = Object.prototype.toString
for(var prop in orign){
if(orign.hasOwnProperty(prop)){
if(typeof(orign[prop]) == 'object' && typeof(orign[prop])== null){
if(toStr.call(orign[prop]) === '[Object Array]'){
target[prop] = []
} else {
target[prop] = {}
}
deepclone(orign[prop],target[prop])
}else {
target[prop] = orign[prop]
}
}
}
return target
}
```