Skip to content

阅读指引

需要注意的是,本章节的文档将站在语言的角度,讲解从编写代码起到运行一个应用的过程,请看下方故事线:

编译阶段

  • 与其他大多数语言一样,JavaScript会经历编译阶段,编译会经历 词法分析语法分析
  • 在编译阶段,需要了解 作用域 , 因为JavaScript的作用域是词法作用域(即静态作用域);
  • 既然作用域是静态的,变量的定义也是静态的,JavaScript最初使用 var 定义变量,并且在编译阶段,使用了一种 声明提升 的方式来收集变量声明;
  • 由于变量的声明提升统一提升到函数作用域,这导致了JavaScript 不存在块级作用域 的缺陷,因此ES6以后,新增了 let/const 两种定义变量的方式来修复此缺陷;
  • let/const 本质与 var 并无二致,也会提升,为了实现在定义前不能使用变量,提出了 暂时性死区 的概念;
  • 作用域的嵌套会形成作用域链(作用域是静态的,因此作用域链也是静态的),结合JavaScript函数是一等公民的特性,产生了函数式编程特有的特性:闭包
  • 利用闭包的特性,可以构造出来 模块 ,这是早期模块的雏形;

运行阶段

  • 经过编译后的代码,开始进入到运行阶段,开始运行前,要为需要运行的代码准备环境,这个就是运行阶段的核心:构建 执行上下文
  • 执行上下文构建阶段最核心的一件事就是 this 的绑定;
  • 其次是作用域链的建立,这里与编译阶段的作用域是一致的;
  • 代码运行时,需要在 堆栈 中分配内存,这里涉及到JavaScript的 内存管理
  • 函数执行时,涉及到在 中进行调度;
  • 除了使用栈供函数调用外,由于JavaScript是异步的,还需要通过 任务队列 调度异步的任务;
  • 为了满足某些需求,任务队列进一步发展出 宏任务微任务
  • 为了更好编写异步代码,ES6新增了 Promise生成器async/await 等特性;