JavaScript的运行过程
执行过程中用到的内容
执行上下文栈 ECS execution context stack
js执行的调用栈,当js代码执行时,这段代码会入栈,执行完成会出栈
全局执行上下文 GEC global execution context
js运行时创建的执行上下文
函数执行上下文 FEC functional execution context
在函数执行时创建的执行上下文,包含函数的AO对象、作用域链、绑定的this
全局对象 GO global object
js引擎在代码执行前会在堆中创建一个全局对象windows(也就是全局上下文)
变量对象 VO variable object
每个执行上下文都有一个变量对象,全局执行上下文的变量对象就是全局对象,函数执行上下文的变量对象就是执行函数的活动对象
函数对象 FO function object
函数在堆内存中的对象,包含函数体。
活动对象 AO active object
函数执行前预编译过程中创建的对象,活动对象中有函数内定义的变量(未赋值)(也就是函数上下文)
执行过程
浏览器解析渲染网页时,会用内核解析DOM. 遇到script标签时,会阻塞DOM解析,并将主线程交给js引擎。
js引擎先进行语义分析和语法分析,遇到语义语法错误会报错并停止解析。
然后js引擎会对代码进行解释和预编译,预编译时会将变量和函数加入全局对象GO中,此时的变量没有赋值,函数则会创建一个函数对象FO,同时将这个对象的指针存入全局对象GO中(如果函数名和变量名相同,函数会将变量覆盖)
此过程完成后就形成了js的抽象语法树(AST),被js引擎转换为二进制交给cpu进行执行。
执行时每个上下文都会关联一个变量对象VO。执行开始时首先是全局对象GO进入执行上下文栈,此时全局执行上下文的变量对象VO就是全局对象GO,执行时遇到变量就给变量赋值,遇到函数调用时就创建一个函数执行上下文FEC,和执行上下文中的变量对象VO(就是函数的活动对象AO,存储着函数中的变量(未赋值)和作用域链)并放入执行上下文栈中。当函数执行完则将函数的执行上下文弹出上下文栈,回到全局上下文执行。最后运行到全局所有代码执行完毕。
全局执行上下文的VO(也就是GO)的属性中保存了声明的变量和函数
函数执行上下文的VO(也就是AO)的属性中保存了声明的变量和函数,与作用域链