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