美文网首页React.js
深入理解浅拷贝和深拷贝

深入理解浅拷贝和深拷贝

作者: 小猿_Luck_Boy | 来源:发表于2018-05-08 16:59 被阅读8次

前言

基本类型和引用类型

ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是那些保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。
而引用类型值是指那些保存堆内存中的对象,意思是变量中保存的实际上只是一个指针,这个指针指向内存中的另一个位置,该位置保存对象。

目前基本类型有:

Boolean、Null、Undefined、Number、String、Symbol(ES6才新出来)

引用类型有:

Object、Array、Function

理解了基本类型和引用类型之后,我们来写一个栗子

var obj1 = {x:1,y:2};
var obj2 = obj1;

console.log(obj1); // {x:1,y:2}
console.log(obj2); // {x:1,y:2}

obj2.x = 3;

console.log(obj1); // {x:3,y:2}
console.log(obj2); // {x:3,y:2}

console.log(obj2 === obj1); // true


上面我们创建了一个对象,分别赋值给obj1和obj2,然后你修改obj1的值,发现obj2的值也跟着改变了。
归根结底我们创建的对象只有一份,只是用2个指针去引用了而已。这就是我们所说的浅拷贝。

浅拷贝

我们来看几个例子

Array
var arr1 = [1, 2], arr2 = arr1.slice();
console.log(arr1); //[1, 2]
console.log(arr2); //[1, 2]

arr2[0] = 3; //修改arr2
console.log(arr1); //[1, 2]
console.log(arr2); //[3, 2]

console.log(arr1 == arr2) //false

我们可以看到利用Array的slice方法进行生产一个新的数组,也就是引用的地址不一样了,会达到深拷贝的效果,这是真的吗?我们在看一下下边的栗子:

var arr1 = [1, 2, [3, 4]], arr2 = arr1.slice();
console.log(arr1); //[1, 2, [3, 4]]
console.log(arr2); //[1, 2, [3, 4]]

arr2[2][1] = 5; 
console.log(arr1); //[1, 2, [3, 5]]
console.log(arr2); //[1, 2, [3, 5]]

console.log(arr1 == arr2) //false

我们可以看到这个api只能对第一层的嵌套进行了深拷贝,对于深层次的引用并没有进行深拷贝,等于这不是真正意义上的深拷贝。

具备同等特性的还有:concat、Array.from()

Object

我们在开发中经常使用Object.assign方法,其实这也是一个浅拷贝的方法

var obj1 = {x: 1, y: 2}, obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{x: 1, y: 2}

obj2.x = 2; //修改obj2.x
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{x: 2, y: 2}

console.log(obj2 === obj1); // false

var obj1 = {
    x: 1, 
    y: {
        m: 1
    }
};
var obj2 = Object.assign({}, obj1);
console.log(obj1) //{x: 1, y: {m: 1}}
console.log(obj2) //{x: 1, y: {m: 1}}

obj2.y.m = 2; //修改obj2.y.m
console.log(obj1) //{x: 1, y: {m: 2}}
console.log(obj2) //{x: 2, y: {m: 2}}

console.log(obj2 === obj1); // false

不难看出,虽然这个方法生成了一个新的实例,但是这个方法仅仅只拷贝了对象的第一层的属性,并没有对深层次的对象发生拷贝。

深拷贝

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

那么怎么实现深拷贝呢?

  1. 利用Jquery.extend方法

  2. 利用lodash的cloneDeep的方法

相关文章

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • 浅拷贝和深拷贝

    本文参考:JavaScript中的浅拷贝和深拷贝js 深拷贝 vs 浅拷贝深入剖析 JavaScript 的深复制...

  • 深拷贝 浅拷贝

    深入认识深拷贝 浅拷贝 公共方法 // 深拷贝 浅拷贝 对于基本类型来说 对于赋值操作 就是 深拷贝 因为值...

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • 简介深浅拷贝

    深浅拷贝 python 直接赋值,浅拷贝和深拷贝 直接赋值 其实就是对象的引用 (可以理解成浅拷贝) 浅拷贝: 拷...

  • iOS之深拷贝与浅拷贝

    深拷贝与浅拷贝是在内存管理中非常重要的概念,理解好深拷贝和浅拷贝也有助于加深对iOS的内存管理的理解。 深拷贝与浅...

  • IOS开发之深拷贝与浅拷贝

    拷贝的方式有两种:浅拷贝和深拷贝。 从字面意思理解,浅拷贝,只是拷贝了对象的指针,而不是拷贝对象本身。 深拷贝,是...

  • 实现一个深拷贝

    深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。 代码中理解...

  • 深入理解浅拷贝和深拷贝

    前言 基本类型和引用类型 ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值...

  • 深入理解深拷贝和浅拷贝

    概念普及 : 对象、可变类型、引用 数据拷贝会涉及到Python中对象、可变类型、引用这3个概念,先来看看这几个概...

网友评论

    本文标题:深入理解浅拷贝和深拷贝

    本文链接:https://www.haomeiwen.com/subject/bcswrftx.html