JavaScript运行机制、预编译、执行期上下文、作用域链、闭包

1.js运行的三部曲

首先,我们需要了解JavsScript在浏览器中运行的三个步骤

语法分析 > 预编译(重点)=>解析执行

  1. 语法分析:整体分析js语法有没有错误,有的话会立即报错并停止运行
  2. 预编译(重点):主要解决执行顺序的问题;(如变量声明提升,函数声明提升等)
  3. 解析执行

2.执行环境及作用域

执行环境也叫执行期上下文。
在这,我们需要先了解几个JavaScript中的几个重要概念

  • 执行期上下文(AO):当函数在执行的前一刻,会创建一个执行期上下文的内部对象。一个执行期上下文对象定义了一个函数执行时的环境,函数每次执行时对应的执行期上下文都是独一无二的,所以每次调用同一函数会导致创建多个执行期上下文对象,当函数执行完毕,执行期上下文被销毁。
  • 作用域([[scope]]):每个JavaScript函数都是一个对象,对象中有些属性我们可以访问,有些我们不可以,这些属性只供JavaScript引擎存取。[[scope]]就是其中一个,[[scope]]就是我们所说的作用域,其中存储了执行期上下文的集合。一个函数被定义时,它的[[scope]]指向的对象(scope chain)的第0位存储的就是该函数所在的执行环境。
  • 作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。
  • 查找变量:在哪个函数里边查找变量,就从哪个函数作用域链的顶端依次向下查找。

例:
JavaScript运行机制、预编译、执行期上下文、作用域链、闭包_第1张图片
JavaScript运行机制、预编译、执行期上下文、作用域链、闭包_第2张图片
JavaScript运行机制、预编译、执行期上下文、作用域链、闭包_第3张图片
JavaScript运行机制、预编译、执行期上下文、作用域链、闭包_第4张图片
JavaScript运行机制、预编译、执行期上下文、作用域链、闭包_第5张图片

3.预编译

3.1全局预编译

  1. 创建GO对象(Global Object,js中windowGO可以理解为Window);
  2. 找变量声明,讲变声名作为GO的属性名,值为undefined;
  3. 找函数声明,函数名作为GO的属性名,函数体作为GO的属性值

3.2函数中的预编译

  1. 创建AO对象(Active Object)(AO也叫执行期上下文)
  2. 找形参和变量声明,将变量和形参作为AO的属性名,值为undefined
  3. 将实参和实参统一
  4. 在函数中找函数声明,函数名作为GO的属性名,函数体作为GO的属性值

4.闭包

  1. 定义:当内部函数被保存到外部时,就生成了闭包。
  2. 闭包的作用:
  • 实现共有变量(累加器)
  • 可以做缓存(存储结构)
  • 可以实现封装和属性私有化
  • 模块化开发,防止污染全局变量(立即执行函数)
  1. 闭包的防范:
    闭包会导致原有的作用域链不释放,造成内存泄漏;
    闭包会导致多个执行函数公用一个私有变量,如果不是特殊需要,应尽量避免这种情况发生。

你可能感兴趣的:(JavaScript)