js之淺拷貝和深拷貝

大雄45發表於2021-10-10
導讀 js資料型別主要分基本資料型別和引用資料型別。前者包括Number,String等,後者主要是Object,因此以下會針對不同的資料型別來分析,需要的朋友可以參考一下

js之淺拷貝和深拷貝js之淺拷貝和深拷貝

1、js記憶體

js記憶體,或者說大部分語言的記憶體都分為棧和堆。基本資料型別的變數值分配在棧上,引用資料型別的變數值分配在堆上,棧中只是儲存具體堆中物件的地址。

2、賦值

對於基本資料型別,賦值操作是拷貝,即新舊變數不會相互影響。

var a = 1;
var b = a;
b = 2;
console.log(b); // 2

對於引用資料型別,賦值操作只是在棧中新增一個指向堆中物件的變數,即複製引用地址。新舊變數之間會互相影響,即在新變數上改變物件值,舊變數對應值也會改變。

var a = {
    name: "mike"
};
var b = a;
b.name = "jack";
console.log(a); // {name: "jack"}
3、淺拷貝

對於基本資料型別和不具有巢狀物件的資料,均是拷貝操作,新舊變數之間不會相互影響。

var a = {
    name: "mike"
};
var b = {};
b.name = a.name;
b.name = "jack";
console.log(a) // {name: "mike"}

但是對於具有巢狀物件的資料,淺拷貝只拷貝第一層物件,深層次的值仍然是複製引用地址。

var a = {
    name: "mike",
    language: {
        first: "english",
        second: "chinese"
    }
};
var b = {};
b.name = a.name;
b.name = "jack";
b.language = a.language;
b.language.first = "japanese"
console.log(a) // { language : {first: "japanese", second: "chinese"}}

js實現淺拷貝,思想:遍歷target的每個屬性,將起屬性名和值賦值給新變數。

如果你明白了賦值的含義,那麼在程式碼的第四行,當此時的target[key]的值是物件的時候,通過賦值賦予新變數,本質上是複製引用資料型別在堆中的地址,就不難理解為什麼淺拷貝對於是否是巢狀物件的有不同結果了。

function shallowCopy(target) {
    let result = {};
    for (const key in target) {
        result[key] = target[key];
    }
    return result;
}
4、深拷貝

深拷貝是完完全全的拷貝,新舊變數之間不會相互影響。

對於引數是否是物件有不同的處理方法,如果是物件,對於物件的每個屬性和值賦值然後遞迴處理; 否則直接返回。

function clone(target) {
    if (typeof target === "object") {
        //判斷是否是陣列
        let result = Array.isArray(target)? [] : {};
        for (const key in target) {
            result[key] = clone(target[key]);
        }
        return  result;
    } else {
        return target;
    }
}

到此這篇關於js中的賦值 淺拷貝和深拷貝詳細的文章就介紹到這了

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2795242/,如需轉載,請註明出處,否則將追究法律責任。

相關文章