天天看點

js對象深度拷貝、Object.assign()、Object.assign()複制非對象

把對象target1, target2,...合并到對象origin上

    Object.assign(origin, target1, target2, ....);

1.合并的是對象

var origin = {
    a: 'a'
},

target1 = {
    a:'a1'
    b: 'b'
},

target2 = {
    c: 'c'
}

//執行
Object.assign(origin, target1, target2);

// origin原有屬性被覆寫,新屬性添加
console.log(origin) // {a:'a1',b:'b',c:'c'}
           

2.合并的值是 數字、空符串 ''、布爾值(false或true) 、undefined、null

var origin = { a: 'a' },

target1 = 1;

// 執行
Object.assign(origin, target1);

// origin不改變:
console.log(origin) // {a:'a'}
           

3.合并的是數組

var origin = { a: 'a' },

target1 =[12, 123];

// 執行
Object.assign(origin, target1)

// target1會被以 索引為屬性,值為屬性值複制到origin
console.log(origin) // {0:12,1:123,a:'a'}


// 如果原對象有0, 1之類的屬性會被替換值
var origin = { 0: 0, a: 'a' },

target1 =[12, 123];
Object.assign(origin, target1)
console.log(origin) // {0:12,1:123,a:'a'}
           

4.合并的是非空字元串

var origin = { a: 'a' },

target1 = 'nihao啊';

// 執行
Object.assign(origin, target1);

// 字元串會被以索引為屬性,值為屬性值複制到origin
console.log(origin) // {0:'n',1:'i',2:'h',3:'a',4:'o',5:'啊',a:'a'}
           

Object.assign方法是淺拷貝即隻有一層值的時候拷貝是沒問題的,拷貝之後,origin和target1的值再改變時是不會互相影響的

拷貝的對象如果有兩層及以上的時候,拷貝之後會互相影響,target1改變 origin也會跟着改變

var origin = { a: 'a' },

target1 = {
    b: { c: 1 }
};

// 執行
Object.assign(origin, target1);
console.log(origin) // 得到{a:'a',b:{c:1}}

// 改變target1中b.c的值
target1.b.c++
console.log(origin) // {a:'a',b:{c:2}} origin也改變了。
           

自定方法實作深度拷貝

function deepClone(origin, target) {

        var target = target || {};

        for (var prop in target) {

            if (target.hasOwnProperty(prop)) {

                if (target[prop] !== null && typeof target[prop] === 'object') {

                    origin[prop] = Object.prototype.toString.call(target[prop]) === '[object Array]' ? [] : {};

                    deepClone(origin[prop], target[prop]);

                } else {
                    origin[prop] = target[prop]
                }
            }

        }

    }

    var obj = {

            name: 'name',

            arr: [1, 2, 3]

        },

        obj1 = {

            obj: { a: 'a' },

        };

    // 執行
    deepClone(obj, obj1)
    console.log(obj)

    /*

    {
	    name: 'name',
	    arr: [1, 2, 3],
	    obj: { a: 'a' }
    }

    */

    // 改變obj1的值
    obj1.obj.a = 'b';

    console.log(obj)
    /*
    {
	    name: 'name',
	    arr: [1, 2, 3],
	    obj: { a: 'a' }
    }
    */

    //obj不會跟随obj1改變