内存分配:
JavaScript在定义变量时就自动完成了内存分配:
//给数值变量分配内存
var num = 123
//给字符串分配内存
var str = "abc"
//给对象及其包含的值分配内存
var obj = {
a: 1,
b: null
}
//给数组及其包含的值分配内存(就像对象一样)
var ary = [1, null, "abc"]
//给函数(可调用的对象)分配内存
function fn(a){
return a
}
//函数表达式也能分配一个对象
element.addEventListener('click', function(){
element.style.color = 'pink'
}, false)
有些函数调用结果是分配对象内存:
//分配一个Date对象
var date = new Date()
//分配一个DOM元素
var ele = document.createElement('div')
有些方法分配新变量或者新对象:
//str2是一个新的字符串,因为字符串是不变量,JavaScript 可能决定不分配内存,只是存储了 [0-3] 的范围
var str1 = "abc"
var str2 = str1.substr(0, 3)
//新数组ary3有四个元素,是ary1连接ary2的结果
var ary1 = ["ab", "cd"]
var ary2 = ["ef", "gh"]
var ary3 = ary1.concat(ary2)
内存模型:
JS内存空间分为栈(stack)、堆(heap)、池(一般也会归类为栈中)
其中栈存放变量,堆存放复杂对象,池存放常量 基础数据类型的变量存储在栈中,引用数据类型的变量存储在堆中,引用数据类型的地址也存储在栈中 访问基础数据类型变量时,直接从栈中读取值 访问引用数据类型变量时,先从栈中读取引用数据类型指向的地址,再根据地址到堆中读取数据
基础数据类型和栈内存
js基础数据类型(简单数据类型):String,Number,Boolean,Null,Undefined
基础数据类型的变量指向的是栈内存中的值 当声明一个变量a时,会在栈内存里面分配一块存放变量a存储的值的内存,当变量a存储的值发生改变时,栈内存里面对应的a存储值的内存里的值也会发生相应改变,如果又声明了一个变量b,并把变量a的值赋值给变量b,此时在栈内存里面会新分配一块存放变量b存储的值的内存,a和b两个变量分别对应两块存储的值相同的栈内存,且两块栈内存互不影响
//将变量a的值赋值给变量b
var a = 1
var b = a
console.log(a) //1
console.log(b) //1
//改变变量a的值,变量b的值不受影响
a = 2
console.log(a) //2
console.log(b) //1
//改变变量b的值,变量a的值不受影响
b = 3
console.log(a) //2
console.log(b) //3
引用数据类型和堆内存
js引用数据类型(复杂数据类型):Object (Array,Date,Function ...)
引用数据类型指向的是其在栈内存中的地址,通过这个地址,指向对应堆内存中的数据 当声明一个对象变量obj时,会在栈内存中分配一块存放obj地址的内存,堆内存中会分配一块内存存放地址指向的obj的数据,如果将obj赋值给另一个对象时,其实是把这个对象在栈内存中的地址传递给了另一个对象,他们共享地址指向的堆内存中的同一块内存和里面存放的数据,如果改变其中一个对象的一个属性,其对应的堆内存中的数据就会被改变,所以另一个对象中的属性也会被改变,如果对其中一个对象重新赋值,这个对象在栈内存中的地址就会指向另一块堆内存, 不再与另一个对象共享同一块堆内存,且两块堆内存互不影响
//将obj1的值赋值给obj2
var obj1 = {
a: 1,
b: 2
}
var obj2 = obj1
console.log(obj1) //{a:1, b:2}
console.log(obj2) //{a:1, b:2}
//改变obj1的属性值,obj2发生相应改变
obj1.a = 3
console.log(obj1) //{a:3, b:2}
console.log(obj2) //{a:3, b:2}
//将obj1重新赋值,obj2的值不受影响
obj1 = {
a: 3,
b: 4
}
console.log(obj1) //{a:3, b:4}
console.log(obj2) //{a:3, b:2}
浅拷贝和深拷贝
浅拷贝:
浅拷贝可以理解为,在栈内存中的拷贝行为,只能拷贝栈内存中的基本值和引用地址
//浅拷贝的简单实现
var obj1 = {
a: 1,
b: 2
}
var obj2 = obj1
console.log(obj1) //{a:1, b:2}
console.log(obj2) //{a:1, b:2}
//浅拷贝只是拷贝栈内存中的引用地址,两个变量共用同一堆内存中的数据
obj1.a = 3
console.log(obj1) //{a:3, b:2}
console.log(obj2) //{a:3, b:2}
深拷贝:
深拷贝可以理解为,同时在栈内存和堆内存中的拷贝行为,不仅拷贝栈内存中的基本值和引用地址,引用地址指向的堆内存中的数据也会被拷贝
//深拷贝的简单实现
var obj1 = {
a: 1,
b: 2
}
var obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj1) //{a:1, b:2}
console.log(obj2) //{a:1, b:2}
//深拷贝拷贝栈内存中的引用地址,也拷贝堆内存中的数据,两个变量拥有不同堆内存中的数据
obj1.a = 3
console.log(obj1) //{a:3, b:2}
console.log(obj2) //{a:1, b:2}
内存生命周期:
- 分配内存:当申明变量、对象、函数的时候,系统会自动完成内存的分配
- 使用内存:使用变量、对象、函数等分配到的内存(读,写)
- 回收内存:使用完毕,不需要时将内存释放归还
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!