天天看點

js數組對象拷貝

數組拷貝

var arr = [{old: 'old'}, ['old']];

var new_arr = arr.concat();

arr[0].old = 'new';

new_arr[1][0] = 'new';

console.log(arr); // [{old: 'new'}, ['new']]

console.log(new_arr); // [{old: 'new'}, ['new']]

// 如果數組元素是基本類型,就會拷貝一份,互不影響,而如果是對象或者數組,就會隻拷貝對象和數組的引用,這樣我們無論在新舊數組進行了修改,兩者都會發生變化。這種叫淺拷貝 

// 深拷貝就是指完全的拷貝一個對象,即使嵌套了對象,兩者也互相分離,修改一個對象的屬性,也不會影響另一個。

for實作數組的深拷貝

var arr = [1,2,3,4,5]

var arr2 = copyArr(arr)

function copyArr(arr) {

    let res = []

    for (let i = 0; i < arr.length; i++) {

     res.push(arr[i])

    }

    return res

}

slice 方法實作數組的淺拷貝

他是将原數組中抽離部分出來形成一個新數組

var arr = [1,2,3,4,5]
var arr2 = arr.slice(0)
arr[2] = 5
           

concat 方法實作數組的淺拷貝

var arr = [1,2,3,4,5]
var arr2 = arr.concat()
arr[2] = 5

           

ES6擴充運算符實作數組的深拷貝

var arr = [1,2,3,4,5]
var [ ...arr2 ] = arr
arr[2] = 5

           

淺拷貝和深拷貝都是對于JS中的引用類型而言的,淺拷貝就隻是複制對象的引用(堆和棧的關系,簡單類型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 則是存入桟中,隻用一個指針來引用值),如果拷貝後的對象發生變化,原對象也會發生變化。隻有深拷貝才是真正地對對象的拷貝。

對象淺拷貝

var object1 = {

               a: 1,

               obj: {

                    b: 'string'

                    }

                       };

                 // 淺拷貝

                var copy = Object.assign({}, object1);

               // 改變原對象屬性

               object1.a = 2;

               object1.obj.b = 'newString';

                console.log(copy.a); // 1

對象深拷貝

var obj = { a: 1, b: { c: 2 }};

// 深拷貝

var newObj = JSON.parse(JSON.stringify(obj));

// 改變原對象的屬性

obj.b.c = 20;

console.log(obj); // { a: 1, b: { c: 20 } }

console.log(newObj); // { a: 1, b: { c: 2 } }

對象必須遵從JSON的格式

 擴充運算符實作對象的深拷貝

var obj = {

  name: 'FungLeo',

  sex: 'man',

  old: '18'

}

var { ...obj2 } = obj

obj.old = '22'

console.log(obj)

console.log(obj2)

數組對象深拷貝

let arr = [1, {a: 2}];

function deepCopy(arr) {
    let copyArr = (arr.constructor === Array) ? [] : {}; // 判斷是數組還是對象
    for(let i in arr) {
        if(typeof arr[i] === 'object') {   // 判斷是值類型還是引用類型
            copyArr[i] = deepCopy(arr[i]);  // 引用類型的話進行遞歸操作
        } else {
            copyArr[i] = arr[i];  // 值類型直接指派
        }
    }
    return copyArr;
}

let copyArr = deepCopy(arr);
console.log(copyArr )  // [1, {a: 2}]
arr[1].a = 3;
console.log(copyArr )  // [1, {a: 2}]
copyArr[1].a = 5;
console.log(arr)       // [1, {a: 2}]