一、通俗解释,嘿嘿嘿
在做开发中,经常能遇到数组拷贝的操作。
初期我经常直接用“=”,但是发现,改副本的值,原始数组的值也随之变化了!!这导致了很多莫名的bug出现。最后一顿搜索骚操作,让我知道了深浅拷贝这回事。
“=”号这种形式,就是浅拷贝。
浅拷贝另一种意义上可以理解为只是同一个数组的别名。
比如,let 苏轼 = [],let 苏东坡; 苏东坡=苏轼。苏轼和苏东坡就是一个人,苏轼写了一首诗,苏东坡将诗给改了三百遍,最后还是苏轼的诗被改了。
深拷贝就是真正意义上的复制copy了,无论怎么改副本,原数组都不会变。
比如,苏轼的父亲是苏洵,属性都是从苏洵那里拷贝过来的。但是是两个人,苏洵有三百首诗,生了苏轼后,苏轼写了两百首,那这两百首是不会算到苏洵头上的。
二、正规解释。。。。。
扯了一番,咱们再从原理上看看,为什么会出现深浅拷贝这种奇异的东西。
因为是内存地址指向不同。
浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层。像字符串、数字就是一层数据,所以深浅拷贝都一样。
但对于所有形式的数组和对象,都要用深拷贝;
内存地址图解
这块涉及到堆栈知识,这里不做解释,可自己另做搜索。
//浅拷贝
let a = new Object();
a.age=12;
let b= a;
b.age=16;
上述代码内存地址指向是这样的

所以深拷贝要做的就是给b做个新的堆内存地址。
三、你最关心的,到底怎么深拷贝
网上流传的有很多种
比如Object.assgin(), 数组的slice(),concat()、JSON.stringfy()、JSON.parse()等等,这些有的支持简单数据,有的检测不到undefined、function这种的。经测试不可行,以下是用过最保险版本,如果你有更好的方式欢迎留言~~~
四、上代码!!!!
let arr1 = [{c:1},{c:2,arr:[{c:1},{c:2},{c:3}]},{c:3},{c:4}];
deepCopy = function (obj) {
var result = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object' && obj[key]!==null) {
result[key] = this.deepCopy(obj[key]); //递归复制
} else {
result[key] = obj[key];
}
}
}
return result;
}
var arr2 = deepCopy(arr1); arr2[1].c = "9"; arr2[1].arr[1].c = "12";
console.log("数组的原始值:" , arr1 ); console.log("数组的新值:" , arr2 );
五、如果对你有帮助,关注,点赞,一条龙走起哈~~~
嘻嘻~~~
啦啦啦啦~~~
网友评论