js堆栈
文章转载自 https://www.jianshu.com/p/b3e81ff877b9
文章转载自 https://www.cnblogs.com/chengguanhui/p/4737413.html
1、栈(stack)和堆(heap)
堆是堆内存的简称,栈是栈内存的简称
栈是自动分配相对固定大小的内存空间,并由系统自动释放;堆是动态分配内存,内存大小不一,也不会自动释放。
2、js的数据类型
· 基本数据类型
Undefined,Null,Boolean,String,Number,Symbol都是直接按值 直接存在栈中,每种类型的数据占用的内存空间大小都是固定的,并且由系统自动分配自动释放
· 引用数据类型
Object,Array,Function这样的数据存在堆内存中,但是数据指针是存放在栈内存中,当我们访问引用数据时,先从栈内存中获取指针,通过指针在堆内存中找到数据
3、传值与传址
基本数据类型与引用数据类型最大的区别实际是传值与传址的区别。
以代码为例
1 let a= [1,2,3,4,5]; 2 3 let b = a; 4 5 let c= a[0]; 6 7 alert(b); // 1,2,3,4,5 8 9 alert(c); // 1 10 11 //改变数值 12 13 b[4] = 6; 14 15 c =7; 16 17 alert(a[4]); // 6 18 19 alert(a[0]); // 1 20
从上面我们可以得知,当我改变b中的数据时,a中的数据也发生了变化;但是当我改变c的数据值时,a却没有发生改变。
这就是传值与传址的区别,因为a是数组,属于引用数据类型,所以它赋予给b的时候传的是栈中的数值(相当于新建了一个不同名”指针“),而不是堆内存中的对象。而c仅仅是从a堆中获取的一个数据值,并保存于栈中。所以b修改的时候,指针会根据地址回到a堆中修改,c则直接在栈中修改,并不能指向a堆内存中。

4、浅拷贝
前面已经提到,在定义一个对象或者数组时,变量存放的往往只是一个地址。当我们使用对象拷贝时,如果属性是对象或者数组时,这时候我们传递的也只是一个地址。因此子对象在访问该属性时,会根据地址回溯到父对象指向的堆内存中,即父子对象发生了关联,两者属性值会指向同一个内存空间。
let a = { key1:'11111'; } function Copy(p){ var c = {}; for(var i in p){ c[i] = p[i]; } return c; } a.key2 = {"小辉","小薇"}; var b = Copy(a); b.key3 = "3333"; alert(b.key1); alert(b.key1); alert(b.key1);
a对象中key1属性是字符串,key2属性是数组。a拷贝到b,12属性均顺利拷贝。给b对象新增一个字符串类型的属性key3时,b能正常修改,而a中无定义。说明子对象中的key3(基本类型)并没有关联到父对象中,所以undefined。
1 1 b.key2.push("大辉"); 2 2 alert(b.key2); //小辉,小薇,大辉 3 3 alert(a.key2); //小辉,小薇,大辉
但是,若修改的属性变为对象或数组时,那么父子对象之间就会发生关联。从以上弹出结果可知,我对b对象进行修改,a,b的key2属性值(数组)均发生了变化。其在内存的状态,可以用下图来表示。

5、深拷贝
或许以上并不是我们在实际编码中想要的效果,我们不希望父子对象之间产生关联,那么这时候可以用到深拷贝。既然属性值类型是数组和或对象时只会传址,那么我们就用递归来解决这个问题,把父对象中所有属于对象的属性类型都遍历赋予子对象即可,测试代码如下:
1 function Copy(p, c) { 2 var c = c || {}; 3 for (var i in p) { 4 if (typeof p[i] === 'object') { 5 c[i] = (p[i].constructor === Array) ? [] : {}; 6 Copy(p[i], c[i]); 7 } else { 8 c[i] = p[i]; 9 } 10 } 11 return c; 12 } 13 a.key2 = ['小辉','小薇']; 14 var b={}; 15 b = Copy(a,b); 16 b.key2.push("大辉"); 17 alert(b.key2); //小辉,小薇,大辉 18 alert(a.key2); //小辉,小薇
由上可知,修改属性b的key2数组时,没有使a对象中的key2数组新增一个值,即子对象没有影响到父对象a中的key2。其存储模式大致如下:

文章转载自 https://www.cnblogs.com/chengguanhui/p/4737413.html

浙公网安备 33010602011771号