Javascript系列之浅复制与深复制

定义

浅复制

若是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操做会互相影响。javascript

深复制

深复制不是简单的复制引用,而是在堆中从新分配内存,而且把源对象实例的全部属性都进行新建复制,以保证深复制的对象的引用图不包含任何原有对象或对象图上的任何对象,复制后的对象与原来的对象是彻底隔离的。java

浅复制

数组浅复制

利用数组方法slice和concat返回新数组特性,进行复制。数组

var arr = [1,2,3];
var new_arr = arr.concat();
arr[0] = 'new';
console.log(new_arr);      //[1, 2, 3]

再来看一组状况:this

var arr = [{name: 'haha'}, [1,2,3]];
var new_arr = arr.concat();
arr[0].name = "lily";
console.log(new_arr.name);      //"lily"

能够看出,若是数组元素是基本数据类型,就会复制一份,互不影响,而若是是对象或者数组,就会只复制对象和数组的引用。code

扩展运算符

var obj = { name: "jack" };
var a = [1, 2];
var b = [3, obj];
a.push(...b);
a   // [1, 2, 3, {name: "jack"}]
a[3].name = "rose";
b   // [3, {name: "rose"}]

Object.assign

var obj = { name: "jack" };
var copyObj = Object.assign({}, obj);
obj.name = "rose";
copyObj   // {name: "rose"}

自定义浅复制

function shallowCopy(obj) {
    if (typeof obj !== 'object') return;
    var new_obj = obj instanceof Array ? [] : {};

    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            new_obj[key] = obj[key];
        }
    }
    return new_obj;
}
var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = shallowCopy(source);
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function }
source.child.name = "lily";
console.log(target.child.name);              //"lily"
source.name = "sam";
console.log(target.name);                   //"source"
source.arr[0] = 5;
console.log(target.arr);                   //"5,2,34"
source.setName = function() { console.log(this.name); };
console.log(target.setName );            //function(){ this.name = "haha";  }

由此能够看出,此方法确实能够复制object和array对象,但没法进行深复制;可是能够复制function。对象

深复制

对象深复制

利用JSON对象的parse和stringify方法。ip

var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = JSON.parse(JSON.stringify(source));
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr:[1,2,34] }
source.child.name = "lily";
console.log(target.name);              //"child"
source.arr[0] = 5;
console.log(target.arr);              //"1,2,34"

由此能够看出,虽然此方法确实能够复制object和array对象,而且进行了深复制,却没法复制function。内存

自定义深复制

function deepCopy(obj) {
    if (typeof obj !== 'object') return;
    var new_obj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            new_obj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return new_obj;
}
var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = deepCopy(source);
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function }
source.child.name = "lily";
console.log(target.child.name);              //"child"
source.name = "sam";
console.log(target.name);                   //"source"
source.arr[0] = 5;
console.log(target.arr);                   //"1,2,34"
source.setName = function() { console.log(this.name); };
console.log(target.setName );            //function(){ this.name = "haha";  }
相关文章
相关标签/搜索