function fn1 () {
let a = {
name: ‘零一’
}
let b = 3
function fn2() {
let c = [1, 2, 3]
}
fn2()
return a
}
let res = fn1()
以上代码的调用栈如下图所示:
图中左侧为栈空间,用于存放一些执行上下文和基本类型数据;右侧为堆空间,用于存放一些复杂对象数据
当代码执行到fn2()
时,栈空间内的执行上下文从上往下依次是 fn2函数执行上下文 => fn1函数执行上下文 => 全局执行上下文
待fn2
函数内部执行完毕以后,就该退出fn2函数执行上下文
了,即箭头向下移动,此时fn2函数执行上下文
会被清除并释放栈内存空间,如图所示:
待fn1
函数内部执行完毕以后,就该退出fn1函数执行上下文
了,即箭头再向下移动,此时fn1函数执行上下文
会被清除并释放相应的栈内存空间,如图所示:
此时处于全局的执行上下文中。JavaScript
的垃圾回收器会每隔一段时间遍历调用栈,假设此时触发了垃圾回收机制,当遍历调用栈时发现变量b
和变量c
没有被任何变量所引用,所以认定它们是垃圾数据并给它们打上标记。因为fn1
函数执行完后将变量a
返回了出去,并存储在全局变量res
中,所以认定其为活动数据并打上相应标记。待空闲时刻就会将标记上垃圾数据的变量给全部清除掉,释放相应的内存,如图所示:
从这我们得出几点结论:
-
JavaScript
的垃圾回收机制是自动执行的,并且会通过标记来识别并清除垃圾数据 -
在离开局部作用域后,若该作用域内的变量没有被外部作用域所引用,则在后续会被清除
补充: JavaScript
的垃圾回收机制有着很