什么是栈堆?
- 堆栈是两种数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。
- 栈:
先进后出
;动态分配的空间 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。 - 堆:队列优先,
先进先出
;由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
数据类型
基本类型
- 基本类型的数据存放在栈里面,是可以直接访问,它们是按照值进行分配的,存放在栈(stack)内存中的简单数据段,数据大小确定,内存空间大小可以分配。拷贝基本类型的数据可以直接通过
赋值
,会在栈里面开辟一个块内存去存放。两者之间没有相互影响。
- Number
- String
- Null
- Undefined
- Boolean
引用类型
- 引用类型的数据存放在堆(heap)内存中里面,变量实际保存的是一个指针,这个指针指向的是堆里面的数据,如果通过赋值的形式去拷贝数据,拷贝过去的数据指针指向一个地址,并不会开创新内存。从而改变被赋值的变量原数据也会发生改变。
- Function
- Object
- Array
- Date
- RegExp
数据拷贝
拷贝基本类型(变量)
- 基本变量数据存在栈里面,因为基本变量的大小确定,内存空间大小可以分类,所以拷贝基本变量会在栈里面开辟一块内存区存放,两则之间不会相互影响。
var a = 2
var b = a
b = 66
console.log(a);
console.log(b);
拷贝引用类型(对象/数组)
- 直接赋值,指向的同一地址,b改变了name,obj1的name也会给改变。
var obj1 = {name:'bangbang',age:18};
var b = obj1;
b.name = 'yanniu';
console.log(obj1);
- 深度拷贝,深度拷贝就是把一个
对象/数组
拷贝到另一个对象/数组
,而且两者的内存和以后的操作都互不影响的拷贝!
var oldObj = {
name:"name",
age:20,
colors:['orange','green','blue'],
friend:{
name:"friend name"
}
}
function deepClone(obj = {}){
if(typeof obj !=='object' ||obj==null){
return obj
}
let result;
if(obj instanceof Array){
result = []
}else{
result = {}
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key] = deepClone(obj[key])
}
}
return result
}
var newObj2 = deepClone(oldObj)
newObj2.friend.name="new friend name"
console.log('oldObj',oldObj)
console.log('newObj2',newObj2)
var oldObj = {
name:"name",
age:20,
colors:['orange','green','blue'],
friend:{
name:"friend name"
}
}
var newObj2=JSON.parse(JSON.stringify(oldObj))
newObj2.friend.name="new friend name"
console.log('oldObj',oldObj)
console.log('newObj2',newObj2)