时间:2021-05-25
JavaScript的内存空间
在JavaScript中,每一个数据都需要一个内存空间。内存空间分为两种,栈内存(stack)与堆内存(heap)
栈是系统自动分配的内存空间,由系统自动释放,堆则是动态分配的内存,大小不定不会自动释放。
基础数据类型
JavaScript中的基础数据类型,这些值都有固定的大小,保存在栈内存中,由系统自动分配存储空间在栈内存空间的值,我们可以直接进行操作,因此基础数据类型都是按照值访问
在栈内存中的数据发生复制的行为时,系统会自动为新变量开辟一个新的内存空间,当复制执行后,两个内存空间的值就互不影响,改变其中一个不会影响另一个
栈内存空间数据复制示例var a = `I am variable a`;var b = a; console.log(b); //`I am variable a`b = `I am variable b`;console.log(a); //`I am variable a`console.log(b); //`I am variable b`引用数据类型
引用类型的值是保存在堆内存中的对象,在JavaScript中我们不能直接操作对象的堆内存空间。因为引用类型的值都是按引用访问的,所以在操作对象时,实际上是操作对象的引用而不是实际的对象。引用可以理解为保存在栈内存中的一个地址,该地址指向堆内存中的一个实际对象
引用类型值的复制,系统会为新的变量自动分配一个新的栈内存空间这个栈内存空间保存着与被复制变量相同的指针,尽管他们在栈内存中的内存空间的位置互相独立但是在堆内存中访问到的对象实际上是同一个,因此,当我们改变其中一个对象的值时,实际上就是改变原来的对象
栈内存空间保存指针(地址),堆内存空间保存实际的对象,我们通过变量访问对象时,实际上访问的是对象的引用(地址)
内存中的栈区域存放变量(基本类型的变量包括变量声明和值)以及指向堆区域存储位置的指针(引用类型的变量包括变量声明和指向内容的指针)
var a = { name : `I am object a`, type : 'object'}var b = a;console.log(b);// {name: "I am object a", type: "object"}b.name = `I am object b`;console.log(a);// {name: "I am object b", type: "object"}console.log(b);// {name: "I am object b", type: "object"}基本类型总结
基本数据类型:
包括:null、undefined、number、string、boolean、symbol(es6)
存放位置:内存中的栈区域中
比较:值的比较,判断是否相等,如果值相等,就相等。一般使用===进行比较,因为==会进行类型的转换
拷贝:赋值(通过(=)赋值操作符 赋值),赋值完成后,两个变量之间就没有任何关系了,改变其中一个变量的值对另一个没有任何影响
引用类型总结
引用数据类型:
包括:数组、对象、函数
存放位置:内存的栈区域中存放变量和指针,堆区域存储实际的对象
比较:是引用的比较(就是地址的比较,变量在栈内存中对应的指针地址相等就指向同一个对象)判断是否为同一个对象,示例如下
我们对JavaScript中引用类型进行操作的时候,都是操作其对象的引用(保存在栈内存中的指针)
赋值、深拷贝和浅拷贝 (Assignment, deep copy and shallow copy)
赋值:两个变量的值(指针)都指向同一个对象,改变其中一个,另一个也会受到影响
所谓拷贝就是复制,通过复制原对象生成一个新的对象
浅拷贝:重新在堆内存中开辟一个空间,拷贝后新对象获得一个独立的基本数据类型数据,和原对象共用一个原对象内的引用类型数据,改变基本类型数据,两个对象互不影响,改变其中一个对象内的引用类型数据,另一个对象会受到影响
var obj = { name: 'Jay Chou', age: 32, song:{ name:'发如雪', year:2007 }}var obj1 = obj;function shallowCopy(obj){ var scObj = {}; for(var prop in obj){ if(obj.hasOwnProperty(prop)){ scObj[prop] = obj[prop] } } return scObj;}var obj2 = shallowCopy(obj);console.log(obj === obj1,'obj === obj1','赋值');console.log(obj === obj2,'obj === obj2','浅拷贝');// true "obj === obj1" "赋值"// false "obj === obj2" "浅拷贝"console.log(obj.song === obj2.song);//trueobj2.song.name='双截棍';obj2.name='Jay';console.log(obj)// {name: "Jay Chou", age: 32, song: {name:'双截棍',year:2007}}console.log(obj1);// {name: "Jay Chou", age: 32, song: {name:'双截棍',year:2007}}console.log(obj2);{name: "Jay", age: 32, song: {name:'双截棍',year:2007}}console.log(obj===obj1)//trueconsole.log(obj===obj2)//false深拷贝:不论是对象内的基本类型还是引用类型都被完全拷贝,拷贝后两个对象互不影响
一种比较简单实现方法是使用var dcObj = JSON.parse(JSON.stringify(obj))
var obj = { name: 'Jay Chou', age: 32, song:{ name:'发如雪', year:2007 }}var dcObj=JSON.parse(JSON.stringify(obj));console.log(dcObj);// {name: "Jay Chou", age: 32, song: {name:'发如雪',year:2007}}console.log(dcObj.song === obj.song);//falsedcObj.name='Jay';dcObj.song.name='双截棍';console.log(obj);// {name: "Jay Chou", age: 32, song: {name:'发如雪',year:2007}}console.log(dcObj);//{name: "Jay", age: 32, song: {name:'双截棍',year:2007}}比较:赋值、深拷贝、浅拷贝
赋值:新对象仍然指向原对象,改变新对象的基本类型和引用类型的值都会使原对象对应的值一同改变
浅拷贝:改变新对象基本类型的值不会使原对象对应的值一起改变,但是改变新对象引用类型的值会使原对象对应的值一同改变
深拷贝:改变新对象基本类型和引用类型的值,都不会影响原对象,两者互相独立,互不影响
以上所述是小编给大家介绍的JavaScript的内存空间、赋值和深浅拷贝详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本节内容深浅拷贝循环方式字典常用方法总结一、深浅拷贝列表、元组、字典(以及其他)对于列表、元组和字典而言,进行赋值(=)、浅拷贝(copy)、深拷贝(deepc
memset函数是内存赋值函数,用来给某一块内存空间进行赋值的;包含在头文件中,可以用它对一片内存空间逐字节进行初始化;原型为:void*memset(void
在python中,给一个对象赋值,实际上就是对象对内存空间存储的值的引用。当我们把对象赋值给另一个变量的时候,这个变量并没有拷贝这个对象,而只是拷贝了这个对象的
C++中指针和引用有什么区别详解1.从内存上来讲系统为指针分寸内存空间,而引用与绑定的对象共享内存空间,系统不为引用变量分配内容空间。2指针初始化以后可以改变指
本文实例讲述了JS赋值、浅拷贝和深拷贝(数组和对象的深浅拷贝)。分享给大家供大家参考,具体如下:深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型