js:JavaScript的赋值、浅拷贝、深拷贝

一、区别

和原数据是否指向同一对象基本数据类型的第一层数据原数据中的子对象
赋值修改会使原数据一同修改修改会使原数据一同修改
浅拷贝修改不会使原数据一同修改修改会使原数据一同修改
深拷贝修改不会使原数据一同修改修改不会使原数据一同修改

二、数据类型

js的数据类型划分方式为 基本数据类型(Undefined,Null,Boolean,Number、String)引用数据类型Object(包含 function、Array、Date)

对于基本数据类型来说,不存在赋值、深浅拷贝这个问题,每次赋值都相当于是一次深拷贝

三、赋值、浅拷贝、深拷贝

已知:基本数据类型的数据存储在栈内存中,引用数据类型的数据存储在堆内存。

假设: [1,[2,3],4]是一个数组,存放在堆内存中,该数据在堆内存的地址为127.0.0.1

则栈内存中的存储数据为a = 127.0.0.1

赋值:增加了一个指针指向已存在的内存地址

修改a后,b会随之改变

var a = [1,[2,3],4];//将[1,[2,3],4] 存放到堆中, a = 127.0.0.1
var b= a;//相当于 b = 127.0.0.1
a[0]='c'//修改数组
a[1][0]='d'
console.log(a)//a = 127.0.0.1 指向 ["c",["d", 3], 4]
console.log(b)//b = 127.0.0.1 指向 ["c",["d", 3], 4]

浅拷贝:申请了一个新的内存,拷贝对象中第一层的基本数据,不拷贝对象中的子对象

既然对于基本数据类型来说,每次赋值都相当于是一次深拷贝,那是不是可以通过循环遍历对象的基本数据,将他的值赋给新对象

var a = [1,[2,3],4];
var b= [];
for (var i in a){
	b[i] = a[i]
}
a[0] = 5
a[1][1] = 6
console.log(a)//[5, [2, 6], 4]
console.log(b)//[1, [2, 6], 4]

注意:a[1]是一个数组,假设堆内存中存储[2,3] 这个数组的地址是127.0.0.2,则循环到b[1] = a[1]这一步时,实际上执行的是b[1] = 127.0.0.2

深拷贝:申请了一个新的内存,并复制其全部内容

既然循环遍历只能拷贝到第一层的基本数据类型,子对象无法拷贝到,那我们可以通过判断每个元素的数据类型,然后递归调用循环遍历,这就是一个简单的深拷贝了

var a = [1,[2,3],4];
function copy(a){
	let res = [];
	for (var i in a){
		if (typeof a[i]==="object"){
		//typeof 判断不准确,建议用Object.prototype.toString.call
			res[i] = copy(a[i])//递归调用copy()
		}else{
			res[i] = a[i]
		}
	}
	return res;
}
var b = copy(a);

a[0] = 5
a[1][1] = 6
console.log(a)//[5, [2,6], 4]
console.log(b)//[1, [2,3], 4]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值