1. 执行上下文
当代码运行时,会产生一个对应的执行环境,在这个环境中,所有变量会被事先提出来(变量提升),有的直接赋值,有的为默认值 undefined,代码从上往下开始执行,就叫做执行上下文。
1.运行环境的种类
- 全局执行上下文:
任何不在函数内部的代码都在全局上下文中。
它会执行两件事:创建一个全局的 window 对象(浏览器的情况下),并且设置 this 的值等于这个全局对象。
一个程序中只会有一个全局执行上下文- 函数执行上下文:
每当一个函数被调用时, 都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序执行一系列步骤。- eval执行上下文
执行在 eval 函数内部的代码也会有它属于自己的执行上下文
(不经常使用 eval)
2.执行栈
一种LIFO(后进先出)的数据结构栈,用来存储代码运行时创建的所有执行上下文。
- 当JavaScript引擎第一次遇到脚本时,他会创建一个全局的执行上下文并压入当前的执行栈。
- 每当引擎遇到一个函数的调用,他会为该函数创建一个执行上下文并压入执行栈的顶部。引擎会执行那些执行上下文位于栈顶的函数,当函数执行完成时,执行上下文从栈顶弹出,控制流程到达当前栈中的下一个执行上下文。
2. 创建执行上下文
- 创建执行上下文分为两个阶段:创建阶段 和 执行阶段
- 创建阶段又分为三部分:this的绑定、创建词法环境组件、创建变量环境组件
一. 创建阶段
1. this的绑定:
- 在全局上下文中,this的值指向全局对象(在浏览器里面,this指向window对象);
- 在函数执行上下文中,this的指向取决于函数是如何被调用的。如果函数被一个引用对象调用,那么this指向那个对象,否则this的值被设置为全局对象或是undefined(在严格模式下)
2. 词法环境:
是一种规范类型,基于ECMAScript代码的词法结构来定义标识符和具体变量以及函数的关联。
一个词法环境由环境记录器和一个可能引用外部词法环境的空值组成。
其中,环境记录器指的是:存储变量和函数声明的实际位置;
外部环境的引用:意味着它可以访问其父级词法环境。
词法环境分为两种:
- 全局环境(在全局执行上下文中) 没有外部环境引用的词法环境。全局环境的外部引用是null。
它拥有内建的 Object/Array/等、在环境记录器内的原型函数(关联全局对象,比如 window 对象)还有任何用户定义的全局变量,并且this的值指向全局对象。- 函数环境: 函数内部用户自定义的变量存储在环境记录器中。并且引用的外部环境可能是全局环境,或者任何包含此内部函数的外部函数。
环境记录器分为两种:
- 声明式环境记录器: 存储变量、函数以及参数
- 对象环境记录器: 定义出现在全局上下文中的变量和函数的关系
3. 变量环境:
同样是一个词法环境,其环境记录器持有变量声明语句在执行上下文中创建的绑定关系。
注意: 在ES6中,词法环境组件和变量环境组件的一个不同:词法环境组件被用来存储函数声明和变量(let和const)声明,而变量环境只用来存储var声明的变量
二. 执行阶段
在此阶段,完成对所有这些变量的分配,最后执行代码
2.执行上下文特点
- 单线程,在主进程上运行
- 同步执行,从上往下按顺序执行
- 全局上下文只有一个,浏览器关闭时会被弹出栈
- 函数的执行上下文没有数目限制
- 函数每被调用一次,都会产生一个新的执行上下文环境
网友评论