Js基本数据类型和对象的存储方式
1,基本数据类型和引用数据类型,
-1基本数据类型 : String Number ,Boolear Null Undefinder
- 2, 引用数据类型 : Object
- 3 ,基本数据类型的数据,变量是直接保存他的值,变量与变量之间是相互独立的,修改一个变量不会影响其他的变量,
- 4 ,引用数据类型的数据,变量是保存的是对象的引用地址(内存地址),
如果的多个变量指向同一个对象,此时修改一个变量属性,会影响其他的变量,
区别:
比较两个变量时 对与基本类型数据 直接比较他的值
对于引用数据类型比较的是地址, 地址相同才相同
js中的变量都是保存在栈内内存中的 ,基本数据类类 的值直接在栈内存中存储,
值与值之间是独立存在的 ,修改一个变量不会影响其他变量,
对象是保存在堆内存中的, 每创建一个新对象,就会在堆内存中开辟一个新的空间, 变量保存的是对象的内存地址(对象的引用)
如果两个变量保存的是同一个对象的引用,当一个通过一个变量修改属性时,另一个也会受影响
对象的拷贝
浅拷贝: 以赋值的形式拷贝应用的对象, 仍指向同一个地址,修改时原对象也会受影响.
Object,assgin , 展开运算符(...)
深拷贝: 她在栈内存中仅仅是存了一个引用的地址,而真正的数据存在堆内存中 ,完全是拷贝了一个新的对象,
修改时原对象不受影响
JSON.pars (), JSON.stringify() 递归 , for in , cloneDeep () ,
深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。 在计算机中开辟一块新的内存地址用于存放复制的对象。
基本数据类型:number,string,boolean,null,undefined,symbol以及未来ES10新增的BigInt(任意精度整数)七类。
引用数据类型(Object类)有常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。
而这两类数据存储分别是这样的 a.基本类型--名值存储在栈内存中,例如let a=1; 当你b=a复制时,栈内存会新开辟一个内存,例如这样:
引用数据类型(Object类)有常规名值对的 无序对象{a:1},数组[1,2,3],以及函数等。
当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。
b.引用数据类型--名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值,我们以上面浅拷贝的例子画个图:
当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。
而当我们a[0]=1时进行数组修改时,由于a与b指向的是同一个地址,所以自然b也受了影响,这就是所谓的浅拷贝
那,要是在堆内存中也开辟一个新的内存专门为b存放值,就像基本类型那样,岂不就达到深拷贝的效果了
浅拷贝:
var a = [1, 2, 3, 4, 5];
var b = a;
a[0] = 2
console.log(a);
console.log(b);
//因为b浅拷贝a, ab指向同一个内存地址(堆内存中存的值)
//b会随着a的变化而变化
//[2, 2, 3, 4, 5]
//[2, 2, 3, 4, 5]
深拷贝:
、用处:例如后台返回了一堆数据,你需要对这堆数据做操作,但多人开发情况下,你是没办法明确这堆数据是否有其它功能也需要使用,直接修改可能会造成隐性问题,深拷贝能帮你更安全安心的去操作数据,根据实际情况来使用深拷贝