var msg = 'hello world'
- 在堆内存中创建全局对象
GO(global object)
,并分配一个内存地址(0xa00
)
- 在栈内存中创建全局上下文,每个上下文中有个
VO
,全局上下文中的VO
指向GO
- 解析代码,词法分析,变量的声明,此时未给变量赋值,或者说是赋值了
undefined
- 执行代码,给变量赋值
function foo(){}
- 在堆内存中创建全局对象
GO(global object)
,图同上,此处略。 - 在栈内存中创建全局上下文,图同上,此处略。
- 解析代码,词法分析,函数
foo
的声明,在堆内存中分配一块内存给foo
函数对象使用,foo
的值为指向函数对象的地址(即0x100
),同时函数对象中保存着父级对象的地址(即0xa00
)
function foo(){
var info = 'foo'
console.log(msg)
}
foo()
var msg = 'hello world'
- 在堆内存中创建全局对象
GO(global object)
- 在栈内存中创建全局上下文
- 解析代码,词法分析,声明变量
msg
初始值为undefined
,foo
是函数则为其分配内存并保存内存地址,foo
函数对象中保存有父级对象的地址 - 执行代码,
foo()
,先创建函数执行上下文和AO(activation object)
对象 - 解析完代码,创建完
AO
对象后,再继续执行,info
变量的赋值,msg
的打印输出,此时msg
先从自己的AO
对象中查找,没找到,则根据作用域链(scope chain)
,沿着其作用域链继续查找,直到找到或到最顶层为止。此处找到了,值为undefined
,进行打印输出。 - 代码继续执行,此时函数
foo
执行完毕,foo
的函数执行上下文从栈中弹出,所在堆中生成的AO
对象也被删除。即回收不被引用的内存。设置msg
的值为hello world
垃圾回收算法:引用计数、标记清除
- 此时代码全部执行完毕,如上图,
foo
引用着一块内存,所以不会被看做成垃圾进行回收,如果设置foo = null
,则该块内存会被回收