javascript的变量存储机制和原理

前言

在了解javascript的变量存储机制之前需要了解javascript的数据类型,在js中,数据类型分为基本数据类型和引用数据类型。二者存在内存中,基本类型存在栈中,引用类型存储在堆里。
想查看javascript数据类型详细介绍请访问:JavaScript数据类型总结
javascript内存生命周期分为三个周期:内存分配(分配所需要的暂时使用的内存大小) ——> 使用期(读、写内存)——> 回收(对于不需要使用的内存将其释放)

var num = 1  // 内存分配
alert(num) // 内存使用
num = null // 内存回收 
1. 栈、堆内存

JS的内存空间分为栈(stack)、堆(heap)、池(一般也会归类为栈中)。其中栈存放变量,堆存放复杂对象,池存放常量,所以也叫常量池。

1. 栈

在js中,栈中存放基本数据类型,并且具有按值访问,存储值大小固定,系统自动分配内存空间,空间小,运行效率高,先进后出等特点。

2. 堆

堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。
在js中,堆中存放引用数据类型,具有按引用访问,存储值大小不固定,由代码指定分配内存空间,空间大,运行效率相对低,无需存储(因为根据引用获取)等特点。
引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。在获取引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

  1. 引用类型的复制
let m = { a: 10, b: 20 };
let n = m;
n.a = 15;
console.log(m.a) // 15

m、n都是引用类型,栈内存中存放地址指向堆内存中的对象, 引用类型的复制会为新的变量自动分配一个新的值保存在变量中, 但只是引用类型的一个地址指针而已,实际指向的是同一个对象, 所以修改 n.a 的值后,相应的 m.a 也就发生了改变。
![(https://img-blog.csdnimg.cn/direct/a48c21591e3a43e6840b055ddd8af992.jpeg)
2. 闭包
闭包是指有权访问另一个函数作用域中变量的函数,函数外面的作用域可以访问函数内部的局部变量。

function fn() {
	var num = 10;
	function fun() {
		conosle.log(num)
	}
	return fun;
}
var f = fn();
f(); // 相当于调用fun(),而fun() 可以访问fn内部的局部变量num。由此形成闭包,实现在函数外部访问内部局部变量。

闭包中的变量并不保存中栈内存中,而是保存在堆内存中。 可以避免使用全局变量,防止全局变量污染。但是可能会造成内存泄漏或溢出。

2. 垃圾回收

垃圾回收方面,栈内存变量基本上用完就回收了,而推内存中的变量因为存在很多不确定的引用,只有当所有调用的变量全部销毁之后才能回收。
垃圾回收机制有两种:1.标记清除, 2.引用计数

1.标记清除:js会对变量做一个标记yes or no的标签以供js引擎来处理,当变量在某个环境下被使用则标记为yes,当超出改环境(可以理解为超出作用域)则标记为no,然后对有no的标签进行释放。

2.引用计数:对于js中引用类型的变量, 采用引用计数的内存回收机制,当一个引用类型的变量赋值给另一个变量时, 引用计数会+1, 而当其中有一个变量不再等于值时,引用计数会-1, 如果引用计数为0, 则js引擎会将其释放掉。

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值