前端零碎问题(五)引用数据类型的拷贝问题

浅拷贝和深拷贝是针对引用数据类型的复制操作,先说下数据类型:

数据类型分为:

  a:基础数据类型(Null,Undefined,Number,String,Boolean);

  b:引用数据类型(Object,Array,RegExp,Date,Function)

浅拷贝:只复制了引用,引用的指针指向的是同一个对象的实例,彼此之间的操作会互相影响

深拷贝:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复制的对象的引用图不包含任何原有对象或对象图上的任何对象,复制后的对象与原来的对象是完全隔离的

这里浅拷贝就不多说了,我们看一下深拷贝如何实现:

1):Array的slice和concat方法

var array=[1,2,3]
var arr1=array.concet() //这里对arr1进行操作不会影响array的值
var arr2=array.slice(0) //这里对arr2进行操作不会影响array的值
//但是这并不是深度拷贝,看如下代码:
var array = [1, [1,2,3], {name:"array"}];
var array_concat = array.concat();
var array_slice = array.slice(0);
//改变array_concat中数组元素的值
array_concat[1][0] = 5;
console.log(array[1]);    //[5,2,3]
console.log(array_slice[1]);  //[5,2,3]
//改变array_slice中对象元素的值
array_slice[2].name = "array_slice";
console.log(array[2].name);   //array_slice
console.log(array_concat[2].name); //array_slice

Array的slice和concat方法都会返回一个新的数组实例,但是这两个方法对于数组中的对象元素却没有执行深复制,而只是复制了引用了,因此这两个方法并不是真正的深复制,

2):JSON对象的parse和stringfy

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.name = "target";
console.log(source.name);   //source
console.log(target.name);   //target
//改变target的child
target.child.name = "target child";
console.log(source.child.name);  //child
console.log(target.child.name);  //target child

这个方法使用较为简单,可以满足基本的深复制需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深复制(而且会直接丢失相应的值),同时如果对象中存在循环引用的情况也无法正确处理

3):jQuery中的extend复制方法

jQuery中的extend方法可以用来扩展对象,这个方法可以传入一个参数:deep(true or false),表示是否执行深复制(如果是深复制则会执行递归复制)

原文地址:https://www.cnblogs.com/gutianer/p/8024157.html