java全栈

js深复制和浅复制

2017-08-10  本文已影响67人  葶寳寳

javaScript的变量类型

JavaScript存储对象都是存地址的,所以浅拷贝会导致obj1obj2 指向同一块内存地址。改变了其中一方的内容,都是在原来的内存上做修改会导致拷贝对象和源对象都发生改变;而深拷贝是开辟一块新的内存地址,将原对象的各个属性逐个复制进去。对拷贝对象和源对象各自的操作互不影响。

浅复制的实现

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

原数组的元素会按照下述规则拷贝:

深复制的实现

JSON对象的parse和stringify

JSON对象是ES5中引入的新的类型(支持的浏览器为IE8+),JSON对象parse方法可以将JSON字符串反序列化成JS对象,stringify方法可以将JS对象序列化成JSON字符串,借助这两个方法,也可以实现对象的深拷贝。

var source = { name:"source", child:{ name:"child" } } 
var target = JSON.parse(JSON.stringify(source));
target.name = "target";  //改变target的name属性

console.log(source.name); //source 
console.log(target.name); //target

target.child.name = "target child"; //改变target的child 
console.log(source.child.name); //child 
console.log(target.child.name); //target child
var source = { name:function(){console.log(1);}, child:{ name:"child" } } 
var target = JSON.parse(JSON.stringify(source));

console.log(target.name); //undefined
var source = { name:function(){console.log(1);}, child:new RegExp("e") }
var target = JSON.parse(JSON.stringify(source));

console.log(target.name); //undefined
console.log(target.child); //Object {}

这种方法使用较为简单,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。

还有一点不好的地方是它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object

如果对象中存在循环引用的情况也无法正确处理。

自定义方法实现深拷贝

function clone(data) {
    if (Array.isArray(data)) {
        let newArr = [];
        for (let i = 0; i < data.length; i++) {
            newArr[i] = clone(data[i]);
        }

        return newArr;
    } else if (data instanceof Object) {
        let obj = {};
        for (let key in data) {
            obj[key] = clone(data[[key]]);
        }
        return obj;
    }else {
        return data;
    }
}

var data =  {
    a: 1,
    b: { f: { g: 1 } },
    c: [ 1, 2, 3 ]
};

var objData = clone(data);
console.log(objData === data);  //false
console.log(objdata.b.f === data.b.f); //false
上一篇 下一篇

猜你喜欢

热点阅读