? ? ? ? ? 拷貝(也稱(chēng)克隆),指的是我們對(duì)從服務(wù)器請(qǐng)求回來(lái)的數(shù)據(jù),進(jìn)行"復(fù)制",我們可以對(duì)副本進(jìn)行修改等操作,不能影響到原來(lái)的數(shù)據(jù),如果修改的數(shù)據(jù)不理想,可以在不向服務(wù)器從新發(fā)送請(qǐng)求的情況下,返回到原來(lái)的數(shù)據(jù),
? ? ? ? ? 淺拷貝和深拷貝的區(qū)別是:淺拷貝只會(huì)拷貝對(duì)象最外部的一層,至于更深層次的對(duì)象,則依然是通過(guò)引用指向同一塊堆內(nèi)存.(意思是,拷貝之后的對(duì)象發(fā)生了變化,原對(duì)象也會(huì)發(fā)生變化);而深拷貝在一定程度上,解決了這個(gè)問(wèn)題
淺拷貝
????????// 淺拷貝函數(shù)
????????????function shallowClone(oldobj) {
????????????? ????const obj = { };? ?//const 常量
? ????????????????for ( let? ?i? ?in? obj) {
? ? ????????????????????obj [i] = oldobj [i];
????????????????? }
????????????????? return obj;
????????????}
????????// 被克隆對(duì)象
????????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的值也會(huì)變(說(shuō)明他們指向了同一段堆內(nèi)存),這種效果并不是我們想要的,所以,出現(xiàn)了深拷貝
深拷貝
? ? 第一種方法--------深拷貝函數(shù)
```
//使用遞歸的方式實(shí)現(xiàn)數(shù)組犁享、對(duì)象的深拷貝
function deepClone1(obj) {
? //判斷拷貝的要進(jìn)行深拷貝的是數(shù)組還是對(duì)象文兢,是數(shù)組的話(huà)進(jìn)行數(shù)組拷貝娱两,對(duì)象的話(huà)進(jìn)行對(duì)象拷貝
? var objClone = Array.isArray(obj) ? [] : {};
? //進(jìn)行深拷貝的不能為空熔掺,并且是對(duì)象或者是
? 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 }? ? ?//新對(duì)象的 i 值變了,原對(duì)象的 i 值并沒(mé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 }? ? ?//得到的效果是和深拷貝函數(shù)的效果一樣
但是,深拷貝的兩種方法,都只能解決普通的深拷貝問(wèn)題,特殊的對(duì)象(函數(shù),正則對(duì)象,構(gòu)造函數(shù),稀疏數(shù)組),這兩種方法還解決不了.
????????????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? //構(gòu)造函數(shù)的指向不一樣
? ? ? ? console.log(newobj.b,oldobj.b);? ? ? //function , function? 拷貝函數(shù)打印的效果是對(duì)的,json.parse方法不行,打印的新對(duì)象為空
? ? ? ? console.log(newobj.c,oldobj.c);? ? ? // {? }, [ empty ]
????????console.log(newobj.d,oldobj.d);? ? ?// {? },? / abc / i
總結(jié):一般情況下,深拷貝的兩種方法就應(yīng)經(jīng)夠用了,如果遇到處理特殊對(duì)象的問(wèn)題,再具體問(wèn)題具體分析吧.
```
// 深克隆
// 循環(huán)遍歷每一個(gè)元素钙勃,判斷是原始值還是引用值
// 如果是原始值祖秒,就直接賦值落包,如果是引用值部蛇,就再次判斷是object,還是array
// 新建 [] || {} 再賦值
// 循環(huán)遞歸
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
}
```