关于堆栈 和深浅拷贝的关系
js 的变量存储类型
变量存储分为两类:
1:基本类型:直接存储在栈中的数据(string ,number ,boolean ,undenfine,null)
2:引用类型:将该对象引用的地址存储在栈中,然后将对象里面的数据存放在堆中。(数组,对象,函数,等)
基本类型的变量是存储在栈中的
如果有以下几个基本类型的变量
var name="jozo"
var city =" guangzhou"
var age=22
那么他的存储结构是一个线性的链条结构, 具有先进后出 和后进先出的性质
栈区 有变量的标志符 和变量的值
引用类型的变量将对象引用的地址存储在栈中,对象的数据存放在堆中
js 不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作什么呢,实际上,我们操作的是对象的引用, 所以引用类型的值是按引用访问的
准确的说,引用类型的存储粗腰内存的栈区和堆区(指内存里面的堆内存)共同完成, 栈区内存保存变量的标志符和指向堆内存中该对象的指针,
假如有一下几个对象
var person1={ name:'jozo'}
var person2={ name="xiaom"}
var person3 ={ name="xiaoq"}
则 这三个对象的内存中保存的情况如下
简单赋值
在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到位新变量分配的位置上
var a = 10;
var b = a;
a ++ ;
console.log(a); // 11
console.log(b); // 10
就是说基本类型在赋值操作后,两个变量是相互不受影响的。
对象引用
var a = {}; // a保存了一个空对象的实例
var b = a; // a和b都指向了这个空对象
a.name = 'jozo';
console.log(a.name); // 'jozo'
console.log(b.name); // 'jozo'
b.age = 22;
console.log(b.age);// 22
console.log(a.age);// 22
console.log(a == b);// true
引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
深拷贝和浅拷贝
最后再来看深拷贝和浅拷贝还有赋值的区别,这样就好理解多了
浅拷贝:也就是拷贝A对象里面的数据,但是不拷贝A对象里面的子对象
深拷贝:会克隆出一个对象,数据相同,但是引用地址不同(就是拷贝A对象里面的数据,而且拷贝它里面的子对象)
赋值:简单赋值和对象引用,对象引用获得该对象的引用地址
一个最简单的对象深拷贝:
var obj = {
name : 'zhl',
age : 30
}
var obj2 = JSON.parse(JSON.stringify(obj));