1. 程式人生 > >javascript淺拷貝深拷貝詳解

javascript淺拷貝深拷貝詳解

clas ret utf 復制代碼 alt 都是 body 理解 simple

一、淺拷貝

淺拷貝在現實中最常見的表現在賦值上面,例如

技術分享
<!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數組,所以兩個數組都是指向同一塊存儲地址中去。

除了這種方法可以實現淺拷貝,還有使用sliceconcat進行淺拷貝

例如:我們測試一次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這兩個方法來說都是淺拷貝,只能拷貝數組中的第一層

二、深拷貝

1.通過內置的js函數

技術分享
function deepCopy(o){
    return JSON.parse(JSON.stringify(o));
}
var a = {a:1,b:2,c:3};
var b = deepCopy(a);
b.a = 4;
alert(a.a); //1        
alert(b.a); //4,將b.a賦值為4,不會影響到a對象,a.a仍是1
技術分享

這種方式很好理解,對一個Object對象而言,

先使用內置的JSON.stringify()函數,將其轉化為字符串 "{"a":1,"b":2}"

此時生成的字符串已經和原對象沒有任何聯系了,再通過JSON.parse()函數,將生成的字符串轉化為一個新的對象{a: 1, b: 2}

而在新對象上的操作與舊對象是完全獨立的,不會相互影響。這種方法的優點就是簡單易懂,使用js內置函數來實現,不需要太大的開銷。

2.以通過自己的方法實現,就是遍歷數組或對象,返回新數組或者對象。

var simpleCopy = function(o){
    if (o instanceof Array) {
        var n = [];
        for (var i = 0; i < o.length; ++i) {
            n[i] = o[i];
        }
        return n;
    } else if (o instanceof Object) {
        var n = {}
        for (var i in o) {
            n[i] = o[i];
        }
        return n;
    }
}

3.如何實現拷貝包含對象或者數組的這種情況呢?那麽就通過遞歸拷貝來實現。

var deepCopy = function(o) {
    if (o instanceof Array) {
        var n = [];
        for (var i = 0; i < o.length; ++i) {
            n[i] = deepCopy(o[i]);
        }
        return n;

    } else if (o instanceof Object) {
        var n = {}
        for (var i in o) {
            n[i] = deepCopy(o[i]);
        }
        return n;
    } else {
        return o;
    }
}

javascript淺拷貝深拷貝詳解