宝哥软件园

详细解释JavaScript堆栈内存和堆内存

编辑:宝哥软件园 来源:互联网 时间:2021-08-26

存储器分配

在编译阶段,除了声明变量和函数以及在环境中查找标识符之外,还进行内存分配。不同类型的数据被分配到不同的内存空间:

堆栈内存:引擎在执行代码时工作的内存空间。除了引擎之外,它还用于存储基本值和引用类型值的地址。堆内存:用于存储一组无序且唯一的引用类型值,可以通过使用堆栈中的键名来获得。示意图:

分配和寻址

引擎无法直接对堆内存中的数据进行操作,导致给同一个变量赋值不同类型的值,会产生完全不同的效果:给变量赋值时,实际上是在创建一个新的值,然后再给新的变量赋值,可以说是真正的‘赋值’;当给一个变量赋值时,实际上是在给一个新变量添加一个指针,指向堆内存中的一个对象,这是一种“寻址”操作。

示例:

//基本值var a=1;var b=a;a=2;console . log(a);//输出:2console . log(b);//输出:1//引用值//变量c和d指向堆中相同的数组var c=[0,1,2];var d=c;c[0]=5;console . log(c);//输出:[5,1,2]console . log(d);//输出:[5,1,2]

浅拷贝

浅层复制可以简单理解为堆栈中发生的复制行为,只能复制基础值和引用值的地址。

实施方式

ES6定义了Object.assign()方法来实现浅拷贝。

示例:

让a={ name: 'Tom ',obj: { age: 19 } }让b=Object.assign({},a);console . log(b);//输出:{name:' Tom ',obj 3360 { age : 20 } } a . name=' Amy ';a . obj . age=20;console . log(a);//输出:{name:' Amy ',obj 3360 { age : 20 } } console . log(b);//输出:{name:' Tom ',obj3360 {age: 20}}数组的slice()方法也是一个轻拷贝示例:var a=[0,[1]];var b=a . slice(0);a[0]=8;a[1][0]=9;console . log(a);//输出:[8、[9]]console . log(b);//Output: [0,[9]]*concat()方法也是一个浅拷贝,这里不再赘述。

深度复制

深度复制可以简单地理解为发生在堆栈和堆中的复制行为。除了复制基本值和引用值的地址,地址指向的堆中的对象也将被复制。

实施方式

将需要深度复制的对象序列化为一个JSON字符串,然后根据这个字符串解析出一个结构和值相同的新对象,可以间接实现深度复制。

示例:

让a={ name: 'Tom ',obj : { age : 19 } } var b=JSON . parse(JSON . stringify(a));console . log(b);//输出:{name:' Tom ',obj 3360 { age :19 } } a . name=' Amy ';a . obj . age=20;console . log(a);//输出:{name:' Amy ',obj 3360 { age : 20 } } console . log(b);//输出:{name:' Tom ',obj3360 {age:19}} *此方法需要确保对象是安全的,例如,属性值不能是未定义的、符号、函数、日期或正则的。

使用$实现深度复制。扩展()方法

美元。extend()方法不是由原生JavaScript提供的,而是属于jquery的。该方法提供的实现深度复制的基本思想是:如果是基值或者引用值而不是对象或者数组,直接赋值;如果是对象或数组,则需要递归,直到达到基本值或对象或数组以外的引用值。

$的代码片段。jquery中的extend()方法:

//如果复制内容是数组或对象,则继续调用扩展函数if(deep copy(jquery . isplayanobject(copy)| |(copy isarray=jquery . isarray(copy))){ if(copy isarray){ copy isarray=false;clone=src jQuery.isArray(src)?src :[];} else { clone=src jquery . isplayanobject(src)?src : { };} target[name]=jQuery.extend(深度、克隆、复制);//如果复制内容不是数组或对象,直接赋值} else if (copy!==未定义){ target[name]=copy;}关于$的想法。extend(),我们可以自己探索深度复制的实现:

示例:

//深度复制函数extend(source){ var target=array . isarray(source)?[] : {};for(源中的var键){ var isObject=Object . prototype . tostring . call(源[键])=='[对象对象]';If(is object | | array . is array(source[key]){//如果是对象或数组,继续调用扩展函数target[key]=extend(source[key]);} else {//递归到对象或数组以外的基本值或引用值,直接赋值target[key]=source[key];} }返回目标;}//测试代码var a={a1: undefined,a2: null,a3: 123,a4: false,a53360' Tom ',a6:符号。对于(' 6 '),obj: {s:' book n: 10 },arr: [1,2,3,[4]],fn : function(){ console . log(999);},now: new Date(),} var b=extend(a);a.a5='艾米';console . log(a . a5);//输出:Amy console . log(b . a5);//输出:toma . obj . s=' pen ';console . log(a . obj . s);//输出:pencon sole . log(b . obj . s);//输出:booka . arr[3][0]=9999;console . log(a . arr[3][0]);//输出:9999 console . log(b . arr[3][0]);//输出:4运行时流程图

结合本课内容,JavaScript的运行时流程图如下:

*本图会根据内容的增加不断补充。

以上是边肖介绍的JavaScript堆栈内存和堆内存的详细集成。希望对大家有帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

更多资讯
游戏推荐
更多+