99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

Javascript學(xué)習(xí)之深拷貝和淺拷貝詳解

發(fā)布時(shí)間:2017-07-14 19:40  回復(fù):0  查看:2040   最后回復(fù):2017-07-14 19:40  
JavaScript 中,存在著這樣的兩種拷貝方式。分別是:深拷貝和淺拷貝,這兩種拷貝在實(shí)際中非常的常見,如果讀者是一個(gè)閱讀源碼的愛好者,相信多多少少對深拷貝和淺拷貝有所了解。本文和大家分享的就是 深拷貝和淺拷貝相關(guān)內(nèi)容,一起來看看吧,希望對大家 學(xué)習(xí)javascript有所幫助。
  一、淺拷貝
  淺拷貝在現(xiàn)實(shí)中最常見的表現(xiàn)在賦值上面,例如
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> 測試 </title>
</head>
<body>
    <script type="text/javascript">
        // 第一個(gè)數(shù)組
        var test=["1","2","3"];
        // 第二個(gè)數(shù)組
        var test2=[];
        test2=test;
        test2[1]="two";
        console.log(test);// 運(yùn)行的結(jié)果是 ["1","two","3"]
    </script>
</body>
</html>
  從上面的例子,我們修改test2 數(shù)組的值,最后打印 test 數(shù)組,發(fā)現(xiàn) test 也跟著改變了。
  其實(shí)這個(gè)就是一個(gè)最淺的淺拷貝,相當(dāng)于test2=test 這個(gè)階段是在將 test 數(shù)組中的存儲(chǔ)地址索引賦值給 test2 數(shù)組,所以兩個(gè)數(shù)組都是指向同一塊存儲(chǔ)地址中去。
  除了這種方法可以實(shí)現(xiàn)淺拷貝,還有使用slice concat 進(jìn)行淺拷貝
  例如:我們測試一次slice 這個(gè)方法
<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 方法對數(shù)組進(jìn)行了深度拷貝,
  同理,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>
  為何這樣已經(jīng)算得上是深拷貝的東西,我又稱之為淺拷貝呢?
  其實(shí)使用slice concat 這兩個(gè)方法部分都是不可以拷貝如下的這種情況的:
  運(yùn)行如下的代碼:
  <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 的值,然后同時(shí)修改 arr1 的值,我們可以看到 arr 也被修改了。
  所以對于 Slice concat 這兩個(gè)方法來說都是淺拷貝,只能拷貝數(shù)組中的第一層
  另外除了可以對數(shù)組進(jìn)行淺拷貝,同樣的我們也可以對JSON 數(shù)據(jù)進(jìn)行淺拷貝
  assign 這個(gè)方法可以對 object 對象進(jìn)行復(fù)制,但是這種拷貝是淺拷貝跟直接賦值卻又是不一樣的。
  assign 其中接受兩個(gè)參數(shù),第一個(gè)參數(shù)指代的是拷貝之后需要修改的內(nèi)容,第一個(gè)參數(shù)指代的是要拷貝的內(nèi)容
  <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>
  運(yùn)行上面的代碼可以看到,obj  里面的值也被修改了
  二、深拷貝
  最簡單的深拷貝就莫過于使用JSON 對象提供的方法。
  我們先來個(gè)例子測試一下:
  <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 對象發(fā)現(xiàn)沒有被修改到,這個(gè)已經(jīng)就是深度拷貝的。
  但是轉(zhuǎn)換后的原來的值類型會(huì)出現(xiàn)丟失,也就是最后的類型一定是Object 類型。
  說道深拷貝,就不能不提Jquery 中中的 extend 方法,這個(gè)方法如果是有學(xué)習(xí)制作插件的同學(xué)應(yīng)該都會(huì)知道,這個(gè)方法用于生成一個(gè)全新的 JSON 對象值。
  其實(shí)這個(gè)本身就是一種深拷貝的應(yīng)用,具體的代碼如下:
<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>
  上面的代碼運(yùn)行的時(shí)候,我們可以看到即使是數(shù)組也是同樣可以深度拷貝的。
  具體的解釋是:因?yàn)樯厦嫖覀円呀?jīng)說過數(shù)組類型其實(shí)就是一種object 類型,那么 extend 方法是用來對 object 類型進(jìn)行深拷貝的,那么也就是滿足了數(shù)組的這一種情況,當(dāng)然博主是沒有去看源碼的,所以如果解釋與源碼有出入,望請指正。
來源: 博客園

您還未登錄,請先登錄

熱門帖子

最新帖子

?