对象的深拷贝与浅拷贝
<h3>对象的深拷贝</h3>
<p>对于对象来说,<strong>深拷贝是开辟新的栈</strong>,两个对象对应不同的地址,修改一个对象不会改变另一个对象的属性;</p>
<p>深拷贝的代码如下:
第一种方法:<strong>通过JSON解决解析</strong></p>
<pre><code class="language-javascript">let judy = {
name:'judy',
age:'16',
friend:['wayne','ade','num'],
sex:'女'
}
//JSON.stringify(data)【从一个对象中解析出字符串】
//解析对象JSON.parse(data)【从一个字符串中解析出json对象】
var newJudy = JSON.parse(JSON.stringify(judy))
newJudy.age = 30;
newJudy.friend.push('hahha');
console.log(newJudy) //{name: "judy", age: 30, friend: Array(4), sex: "女"}
console.log(judy) //{name: "judy", age: "16", friend: Array(3), sex: "女"}</code></pre>
<p>第二种方法:<strong>通过递归解析解决</strong></p>
<pre><code class="language-javascript">var china = {
nation : '中国',
birthplaces:['北京','上海','广州'],
skincolr :'yellow',
friends:['sk','ls']
}
//深复制,要想达到深复制就需要用递归
function deepCopy(o,c){
var c = c || {}
for(var i in o){
if(typeof o[i] === 'object'){
//要考虑深复制问题了
if(o[i].constructor === Array){
//这是数组
c[i] =[]
}else{
//这是对象
c[i] = {}
}
deepCopy(o[i],c[i])
}else{
c[i] = o[i]
}
}
return c
}
var result = {name:'result'}
result = deepCopy(china,result)
console.dir(result)</code></pre>
<h3>对象的浅拷贝</h3>
<p>浅拷贝是对<strong>对象地址的复制</strong>,并没有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改一个对象的属性,则另一个对象的属性也会变化</p>
<pre><code class="language-javascript">const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
// 对象的浅拷贝
var o1 = {a: 1};
var o2 = o1;
console.log(o1 === o2); // =>true
o2.a = 2;
console.log(o1.a); // => 2
// 数组的浅拷贝
var o1 = [1,2,3];
var o2 = o1;
console.log(o1 === o2); // => true
o2.push(4);
console.log(o1); // => [1,2,3,4]</code></pre>
<p>文章转自链接:<a href="https://www.zhihu.com/question/23031215">https://www.zhihu.com/question/23031215</a></p>
<p><a href="https://juejin.im/post/5b5d3f54e51d453467551604">https://juejin.im/post/5b5d3f54e51d453467551604</a></p>
<h4>总结 : 由于a和b都是引用类型,采用的是地址传递,a将地址传递给b,那么a和b必然指向同一个地址(引用类型的地址存放在栈内存中)这个地址都指向堆内存中引用类型的值,因此当b改变这个地址类型的值,因为a也指向这个地址,所以a的值也发生变化。</h4>
<pre><code>就好比是a租了一间房,将房间的地址给了b,b通过地址找到了房间,那么b对房间做的任何改变(添加了一些绿色植物)对a来说肯定同样是可见的。</code></pre>
<p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/14f7dbd6b183d1ff346db289ca964b0c?showdoc=.jpg" alt="" /></p>
<p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/67bcd8766324413c4bb4099f7aea4ea1?showdoc=.jpg" alt="" /></p>
<h5>注意:只实现1层的拷贝!!!但上面代码只能实现一层的拷贝,无法进行深层次的拷贝,封装函数再次通过对象数组嵌套测试如下:</h5>
<p>结果证明,无法进行深层次的拷贝,这个时候我们可以使用深拷贝来完成,所谓深拷贝,就是能够实现真正意义上的数组和对象的拷贝,我们通过递归调用浅拷贝的方式实现。</p>
<p>深拷贝代码封装如下:
<img src="https://www.showdoc.cc/server/api/common/visitfile/sign/97d94633f9a2279b94ac414f5c9b9fd4?showdoc=.jpg" alt="" /></p>
<pre><code class="language-javascript">function deepClone(obj){
var ArrayObj = Array.isArray(obj) ? [] : {};
if(obj && typeof(obj) == 'object'){
for(var key in obj){
if(obj.hasOwnProperty(key) ){
if(obj[key] && typeof(obj[key]) == 'object'){
ArrayObj[key] = deepClone(obj[key])
}else{
ArrayObj[key] = obj[key];
}
}
}
}
return ArrayObj;
}</code></pre>
<p>结果证明上面的代码可以实现深层次的克隆。
同时也可以用jquery下面的extend工具方法实现:jQuery.extend([deep], target, object1, [objectN]);</p>
<p>第一个参数设置为true,则jQuery返回一个深层次的副本,递归地复制找到的任何对象。</p>
<p><a href="https://www.cnblogs.com/dobeco/p/11295316.html">https://www.cnblogs.com/dobeco/p/11295316.html</a></p>