javascript
javascript深拷贝和浅拷贝
在JavaScript中,存在著這樣的兩種拷貝方式。分別是:深拷貝和淺拷貝,這兩種拷貝在實際中非常的常見,如果讀者是一個閱讀源碼的愛好者,相信多多少少對深拷貝和淺拷貝有所了解。
?
一、淺拷貝
淺拷貝在現實中最常見的表現在賦值上面,例如
<!DOCTYPE?html><html?lang="en"><head><meta?charset="UTF-8"><title>測試</title></head><body><script?type="text/javascript">//第一個數組var?test=["1","2","3"];????????//第二個數組var?test2=[];test2=test;test2[1]="two";console.log(test);//運行的結果是["1","two","3"]</script></body></html>
從上面的例子,我們修改test2數組的值,最后打印test數組,發現test也跟著改變了。
其實這個就是一個最淺的淺拷貝,相當于test2=test這個階段是在將test數組中的存儲地址索引賦值給test2數組,所以兩個數組都是指向同一塊存儲地址中去。
除了這種方法可以實現淺拷貝,還有使用slice和concat進行淺拷貝
例如:我們測試一次slice這個方法
?
<script?type="text/javascript">????var?arr=["demo1","demo2","demo3"];????var?arr2=arr.slice(0);arr2[1]="test";console.log(arr);//["demo1","demo2","demo3"]console.log(arr2);//["demo1","test","demo3"]</script>
從上面的例子我們可以看出,使用slice方法對數組進行了深度拷貝,
同理,concat的用法如下
?
<script?type="text/javascript">????var?arr=["demo1","demo2","demo3"];????var?arr2=arr.concat();arr2[1]="test";console.log(arr);//["demo1","demo2","demo3"]console.log(arr2);//["demo1","test","demo3"]</script>
為何這樣已經算得上是深拷貝的東西,我又稱之為淺拷貝呢?
其實使用slice和concat這兩個方法部分都是不可以拷貝如下的這種情況的:
運行如下的代碼:
?
<script?type="text/javascript">????var?arr?=?[1,3,[4,7,65,9]];????var?arr1=arr.slice(0);arr1[2][2]=2;console.log(arr1[2][2]);console.log(arr);</script>
?
或者是如下的這一段代碼:?
<script?type="text/javascript">????var?arr?=?[1,3,[4,7,65,9]];????var?arr1=arr.concat();arr1[2][2]=2;console.log(arr1[2][2]);console.log(arr);</script>
?
我們都可以看到,我們拷貝了arr的值,然后同時修改arr1的值,我們可以看到arr也被修改了。
所以對于Slice和concat這兩個方法來說都是淺拷貝,只能拷貝數組中的第一層
另外除了可以對數組進行淺拷貝,同樣的我們也可以對JSON數據進行淺拷貝
assign這個方法可以對object對象進行復制,但是這種拷貝是淺拷貝跟直接賦值卻又是不一樣的。
assign其中接受兩個參數,第一個參數指代的是拷貝之后需要修改的內容,第一個參數指代的是要拷貝的內容
<script?type="text/javascript">????var?obj?=?{?a:?{a:?"hello",?b:?21}?};?var?initalObj?=?Object.assign({b:{"test":1111}},?obj);?initalObj.a.a?=?"changed";?console.log(obj);console.log(initalObj);console.log(obj.a.a);?//?"changed"console.log(obj===initalObj);//false</script>
?
運行上面的代碼可以看到,obj 里面的值也被修改了
?
二、深拷貝
?最簡單的深拷貝就莫過于使用JSON對象提供的方法。
?我們先來個例子測試一下:
?
<script?type="text/javascript">????var?json={????????"a":"test",????????"b":"test1"};????var?b=JSON.parse(JSON.stringify(json));b.a="demo";console.log(json);//{"a":"test","b":"test1"}</script>
?
我們修改了b中的值,但是打印json對象發現沒有被修改到,這個已經就是深度拷貝的。
但是轉換后的原來的值類型會出現丟失,也就是最后的類型一定是Object類型。
說道深拷貝,就不能不提Jquery中中的extend方法,這個方法如果是有學習制作插件的同學應該都會知道,這個方法用于生成一個全新的JSON對象值。
其實這個本身就是一種深拷貝的應用,具體的代碼如下:
?
????<script?src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script><script?type="text/javascript">????????var?arr=["test",["demo1","demo2"]];????????var?arr1=$.extend({},arr);arr[1][0]=1;console.log(arr1);????</script>
?
上面的代碼運行的時候,我們可以看到即使是數組也是同樣可以深度拷貝的。
轉載于:https://blog.51cto.com/13111614/1946186
總結
以上是生活随笔為你收集整理的javascript深拷贝和浅拷贝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 社交背水一战?校园日记背后,支付宝野心你
- 下一篇: 记一次TCP连接异常故障解决