js运行分为三个阶段
语法分析
js代码执行前会全局进行代码语法检查,不正确的语法会抛出错误异常并停止代码执行。
预编译
预编译阶段主要根据不同的环境是生成上下文,主要环境有:
- 全局环境一开始会创建全局对象GO(Global Object)
- 函数环境
创建执行上下文主要做了三件事:
- 生成变量环境(Variable Object)简称VO
- 创建作用域链(ScopeChain)
- 确定
this指向
变量环境
创建变量环境主要步骤:
- 创建
arguments对象 - 检查函数
function声明,创建属性,属性值为函数所在的堆内存地址引用. - 检查变量声明创建属性,属性值为
undefined. 以下代码示例
function test(a, b) {
console.log(a)
console.log(foo()) // Function foo 函数声明提升
var a = 1; // 变量声明
function foo() { // Function foo 函数声明提升
return 2
}
}
test(1, 2)
生成的变量环境为
testEC = {
VO:{
arguments:{
a: undefined,
b: undefined,
length:2,
},
foo: <foo reference>,
a: undefined,
},
//作用域链
scopeChain:[],
//this指向
this: window
}
作用域链
代码解释执行的时候会查找变量的赋值,如果当前作用域没有,就好从上级作用域查找,知道全局作用域查到位置,这个过程形成的链条叫做作用域链.
this指向
this的指向根据不同的环境场景指向都不同
js引擎会把多个下上下文存储到函数调用栈,栈地必定是全局上下文,栈定是执行上下文。栈后进先出的原理,栈顶是最先执行的也就是执行上下文。
解释执行
js是解释性语言,解释一行执行一行.
关于活动对象(AO)和变量对象(VO)的关系
执行到函数的时候,函数会创建一个AO可以理解为VO的实例VO(Context) === AO,多次调用函数时会生成多个AO,但VO是同一个。