JavaScript数据存储方式之深拷贝与浅拷贝

一、JavaScript中数据的存储方式

首先,JavaScript中的数据类型可大致分为两种:基本数据类型和引用数据类型,其中,基本数据类型有Number,String,Undefined,Null,Boolean,Symbol(es6新增)这六种,引用数据类型有Object,Array,Function三种,而这两种类型的数据存储方式是不同的。这里会涉及到数据结构中栈和堆的概念,接下来我会使用图的方式来解释

1.基本数据类型的变量和值都维护在栈区

var a = 123;
var b = a;
a = 456;

 首先,我们先声明了a变量,并赋值给a一个123的值,然后我们再声明一个b变量,将a变量赋值给b变量,这里大家其实不难看出,a和b两个变量的值都是123,因为a变量的声明和赋值都在b变量的前面,所以用图来表示栈区的数据就如下图一样储存,一个变量对应一个值

再之后,我们给a变量又重新赋值为456,这时a变量的值就为456,b的值还是123,如图:

结论:从这个简单的例子中,我们可以得出一个结论,基本数据类型存储在栈中,独立存在并且互不影响

2.引用数据类型的变量维护在栈区,它的值维护在堆区

var a = {
    name:'lisi'
}
var b = obj1

 在这里我们声明了两个对象:a和b,给obj1对象中添加一个name属性,值为lisi,然后将a赋值给b。从下图中不难看出,引用数据类型的变量存储在栈中,它的值在堆中,那我们是怎么通过变量名获取到值的呢?大家注意看图中的0x123,这个其实是数据存储的地址,我用0x123代替数据地址这个概念,数据存储在0x123这个地址中,那我们如何拿到它,在栈区中,将地址与变量对应存储不就行了吗,我们使用数据时,通过变量在栈中寻找到数据存储地址,再通过数据存储地址寻找到数据的值

 为什么这里a和b两个变量都指向name='lisi'这个值呢?因为对象之间的赋值并不是将我对象的数据copy一份给你,而是将我的数据存储地址copy给你,地址相同,那数据肯定也是一样的,这里就会延展出一个问题(深拷贝与浅拷贝):当我修改一个对象里的值的时候,另一个对象里的值会不会改变?这里可以先告诉大家答案,会!!

二、什么是深拷贝、浅拷贝

深拷贝与浅拷贝的概念其实就是从上面这个问题延伸出来的,怎么才可以修改一个对象的值,另一个对象的值不会改变?

深拷贝:指克隆对象,产生新的堆内存空间

浅拷贝:指仅拷贝引用地址

像上述将对象a赋值给对象b的操作就是属于浅拷贝,仅仅将数据引用地址给复制过去,当数据发生改变时,所有指向这个数据的变量都会发生改变,而深拷贝就不一样了,我们是创建一个新的对象赋值给变量,数据引用地址已经发生改变,当我们操作数据的时候就不会影响到其他的变量,而我们想要实现深拷贝就需要沿着这个思路去想办法。

三、实现深拷贝的几种方法

1.通过JSON对象实现深拷贝(JSON.stringify方法,JSON.parse方法)

var a = {
  a:1,
  b:2
}
//先用JSON.stringify将a转成字符串,再用JSON.parse把JSON字符串转为对象
var b = JSON.parse(JSON.stringify(a)) 
console.log(a === b); // => false

2.通过object.assign()实现

var target = { a: 1, b: 2 };
var returnedTarget = Object.assign({},target);
console.log(target === returnedTarget);   // => false

3.lodash函数库 clonedeep方法

var objects = [{ 'a': 1 }, { 'b': 2 }];
 
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);     // => false

4.通过递归的方式

5.三点运算符,解构作用,将原来的对象中的键值对拆借出来形成新的对象

var a = {
  a:1,
  b:2
}
var b = {...a}
console.log(a === b);  // => false

感谢大家抽出时间阅读

推荐大家两个非常实用的网站,可以查JavaScript的很多api,方法,非常好用

https://developer.mozilla.org/zh-CN/

https://www.lodashjs.com/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值