[ JS ] 对象的深拷贝和浅拷贝总结

JS的传值和传址

在使用一个变量给另一个变量赋值时,根据变量类型不同可以分为传址和传值两种传递方式。基本数据类型都是传值,对象,数组都是传址。

传值

顾名思义,传值就是把变量所在的内存里面的值传给另一个变量

var a=1;
var b=a; //b=1

在上面的例子中,b另外开辟了一个空间来存储a的值,因此,对a和b的操作时相互独立的,对其中任何一个进行操作都不会影响对方。
在这里插入图片描述

传址

顾名思义,传址传的是变量的地址,而不是内存空间里面的值。对象都是通过引用存储和赋值的,变量存储的不是对象本身,而是对象在内存中的地址,即引用。对象在赋值时,将对象的引用传递给另外一个变量。
对象就像时一个带锁的抽屉,抽屉里面的东西就是对象里面的值,钥匙就是对象的地址,在复制时,只是把钥匙复制了一份,两把钥匙作用的是同一个抽屉,因此,两个引用的操作会互相影响。这就是浅拷贝。

var a={};
var b=a;

在这里插入图片描述

对象的浅拷贝和深拷贝

浅拷贝

如果只复制了对象的引用,这时对象的内容只有一份,持有该引用的变量都可以对对象进行操作并会互相影响。

深拷贝

使用 for in 进行深拷贝

为了避免对象被随意更改,我们在复制对象的时候,更多的在内存中再开辟出一个空间,然后将原来对象的属性和值都复制到新的空间中去,在最原始级别下复制对象。
我们可以使用 for in 循环来实现。

let user = {
  name: "John",
  age: 30
};

let clone = {}; // 新的空对象

// 复制所有的属性值
for (let key in user) {
  clone[key] = user[key];
}

// 现在的复制是独立的了
clone.name = "Pete"; // 改变它的值

alert( user.name ); // 原对象属性值不变
使用Object.assign 进行深拷贝

assign的语法

Object.assign(dest,[ src1, src2, src3...])

dest是复制之后的对象。dest后面的参数是要复制的对象,这里可以同时复制多个对象,如果他们有相同的属性,那么该属性只会保留最新的赋值。

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// 把 permissions1 和 permissions2 的所有属性都拷贝给 user
Object.assign(user, permissions1, permissions2);

// 现在 user = { name: "John", canView: true, canEdit: true }
两种深拷贝方式存在的问题

我们在复制对象时新建了一个空间来存储对象,因此两个对象按理说是不会互相影响的。但是,万一对象的某个属性也是一个对象呢,那我们在复制时只不过把同一个对象的引用写在了两个地方,这里还是浅拷贝。
在复制对象的属性时,我们要逐个判断该属性是不是一个对象,如果属性是一个对象,那么也要对它进行拷贝。
到这里才是完完全全的深拷贝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值