一、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变量的前面,所以用图来表示栈区的数据就如下图一样储存,一个变量对应一个值。

JS把数据存储在sessionStorage中 js数据存储方式_数据

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

JS把数据存储在sessionStorage中 js数据存储方式_数据_02

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

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

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

我们使用数据时,通过变量在栈中寻找到数据存储地址,再通过数据存储地址寻找到数据的值

JS把数据存储在sessionStorage中 js数据存储方式_数据_03

 为什么这里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

感谢大家抽出时间阅读