前言
JavaScript 执行的过程涉及到了大部分的语言核心逻辑,了解执行上下文(Execution Context),对 JS 的深入理解和开发都是极为重要的。
简介
JS是一种解释性语言,解释一行执行一行。执行上下文是对 JS 代码进行解释、执行、回收。由此涉及的知识点包括 Event Loop(事件循环)、堆(heap)栈(stack)、GC(JS 的垃圾回收机制)、任务队列(宏任务 macrotask、微任务 microtask)、变量提升、明确作用域、作用域链、this 的指向、JS线程和GUI线程的执行机制。
以上及相关的点,这里就不一一展开了。所以执行上下文是了解 JS 核心的第一步,也是 JS 语言中的 “主线任务”。
正文
“把大象放进冰箱需要几步?” 对,是三步:
一、创建上下文(解释阶段)
Tip:如果变量名与函数名相同,变量会被函数覆盖,在执行过程的时候,变量的赋值会覆盖掉这个问题。所以,函数名和变量名最好不要重复
1、全局上下文:
一个程序中只能有一个全局上下文,并将 this 指向全局
2、函数上下文:
函数被调用时创建。每个函数都有自己的上下文,函数执行上下文中会多出 this arguments 和函数的参数。
3、eval 函数上下文:
MDN不建议使用的函数,这里不讨论
二、执行上下文(执行阶段)
执行变量赋值、代码执行
Event Loop 的整个过程:
涉及执行栈(看做水桶,先进后出)、任务队列(看做排队,先进先出。任务队列分为微任务队列、宏任务队列)
V8 引擎的编译机制:
代码 -> AST语法树 -> 字节码 -> 机器码 -> 执行;这里面还涉及词法分析、语法分析、热点函数、反编译等机制
在执行栈中的任务被执行后,会被弹出,等待回收机制的判断,释放内存。
三、回收上下文(垃圾回收阶段)
任务被之后弹出执行栈,回收机制会检查该变量是否有被引用或标记如没有,出栈等待虚拟机回收执行上下文。全局上下文只有唯一的一个,它最早进栈,浏览器关闭时出栈
例:
1、var a = [1、2、3]; 整个执行过程中没有被使用,也没有被置空,该内存一直保持引用数量为1,不会进入回收机制。所以,不要声明未使用的变量,很多语法检查工具中也会有该项的检测、提示。
2、如果形成闭包,闭包对外部变量的引用得不到释放,也会保持引用,不进入回收
最后
后面会按照执行上下文的顺序分享每一个涉及到的点,这里就不展开了。如有不对,欢迎指出!文章来自微信公众号:前端学海