1. 程式人生 > 實用技巧 >js實現深拷貝的5種方式

js實現深拷貝的5種方式

實現深拷貝的方式

  1. JSON方法實現
//_tmp和result是相互獨立的,沒有任何聯絡,有各自的儲存空間。
let deepClone = function (obj) {
    let _tmp = JSON.stringify(obj);//將物件轉換為json字串形式
    let result = JSON.parse(_tmp);//將轉換而來的字串轉換為原生js物件
    return result;
};

let obj1 = {
    weiqiujaun: {
        age: 20,
        class: 1502
    },
    liuxiaotian: {
        age: 21,
        class: 1501
    }
};

let test = deepClone(obj1);
console.log(test);1234567891011121314151617181920

2.用for…in實現遍歷和複製

function deepClone(obj) {
    let result = typeof  obj.splice === "function" ? [] : {};
    if (obj && typeof obj === 'object') {
        for (let key in obj) {
            if (obj[key] && typeof obj[key] === 'object') {
                result[key] = deepClone(obj[key]);//如果物件的屬性值為object的時候,遞迴呼叫deepClone,即在吧某個值物件複製一份到新的物件的對應值中。
            } else {
                result[key] = obj[key];//如果物件的屬性值不為object的時候,直接複製引數物件的每一個鍵值到新的物件對應的鍵值對中。
            }

        }
        return result;
    }
    return obj;
}

let testArray = ["a", "b", "c", "d"];
let testRes = deepClone(testArray);
console.log(testRes);
console.log(typeof testRes[1]);

let testObj = {
    name: "weiqiujuan",
    sex: "girl",
    age: 22,
    favorite: "play",
    family: {brother: "son", mother: "haha", father: "heihei"}
};
let testRes2 = deepClone(testObj);
testRes2.family.brother = "weibo";
console.log(testRes2);

3.利用陣列的Array.prototype.forEach進copy

let deepClone = function (obj) {
    let copy = Object.create(Object.getPrototypeOf(obj));
    let propNames = Object.getOwnPropertyNames(obj);
    propNames.forEach(function (items) {
        let item = Object.getOwnPropertyDescriptor(obj, items);
        Object.defineProperty(copy, items, item);

    });
    return copy;
};

let testObj = {
    name: "weiqiujuan",
    sex: "girl",
    age: 22,
    favorite: "play",
    family: {brother: "wei", mother: "haha", father: "heihei"}
}
let testRes2 = deepClone(testObj);
console.log(testRes2);

4.淺拷貝(使用object.assign方法)

let target=[];
let testArr=[2,3,5,8];
Object.assign(target,testArr);
console.log(target);
testArr.push(8);
console.log("我是原來的"+target+",我是現在的"+testArr);

5。遞迴

var obj = {
        name:"admin",
        age:18,
        sex:"女",
    }
    var obj2 = {};
    for(var i in obj){
        obj2[i] = obj[i];
    }
    obj2.name = "root";
    console.log(obj.name);  //admin
    console.log(obj2.name);  //root
```####改變深拷貝的封裝函式
```js
   [{}, [], true]
        // 定義一個深拷貝函式  接收目標target引數
        function deepClone(target) {
            // 定義一個變數
            let result;
            // 如果當前需要深拷貝的是一個物件的話
            if (typeof target === 'object') {
                // 如果是一個數組的話
                if (Array.isArray(target)) {
                    result = []; // 將result賦值為一個數組,並且執行遍歷
                    for (let i in target) {
                        // 遞迴克隆陣列中的每一項
                        result.push(deepClone(target[i]))
                    }
                    // 判斷如果當前的值是null的話;直接賦值為null
                } else if (target === null) {
                    result = null;
                    // 判斷如果當前的值是一個RegExp物件的話,直接賦值    
                } else if (target.constructor === RegExp) {
                    result = target;
                } else {
                    // 否則是普通物件,直接for in迴圈,遞迴賦值物件的所有值
                    result = {};
                    for (let i in target) {
                        result[i] = deepClone(target[i]);
                    }
                }
                // 如果不是物件的話,就是基本資料型別,那麼直接賦值
            } else {
                result = target;
            }
            // 返回最終結果
            return result;