下面这段代码是如何执行的呢
js
var message = "why"
function foo(){
var message = "foo"
console.log(message)
}
var num1 = 20
var num2 = 30
var result = num1 + num2
console.log(result)
foo()
全局代码执行之前
- JS 引擎在执行代码之前,先在堆内存中创建一个全局对象 GO 。该对象所有的作用域都可以访问。 在浏览器中这个对象就是 window,里面有 Date Array Number setTimeout等等,还会有一个 window 属性指向自己。

- JS 引擎中有一个执行上下文栈,用于执行代码的调用栈,用来执行全局的代码块
- 全局的代码块为了执行,会创建一个全局执行上下文,被放入全局执行上下文栈中
- 在代码执行之前,代码转换 AST 的过程中 ,会将全局定义的变量、函数加入到全局对象 GO中,这个过程是变量的作用域提升 ,这些变量提升之后,var定义的变量赋值是undefined,函数赋值地址。
- 每一个执行上下文会关联一个 VO(变量对象) ,变量和函数声明会被添加到这个 VO 对象中,在全局执行上下文 VO = GO,VO是执行上下文中的概念,GO是堆内存中概念。 在下图中,函数对象中的name是foo,外层作用域就是GO了
全局代码执行之后
- 普通变量赋值
- foo函数执行
- 当执行到函数时,会根据函数体创建一个函数执行上下文(FEC)并被压入到全局执行上下文栈中。
- 并在堆内存中创建AO对象,每一个执行上下文都有 VO 对象,在函数中 VO=AO
函数执行前:

函数执行后: