执行环境(Execution Context,也称为"执行上下文")是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其它数据,决定了各自的行为。当JavaScript代码执行的时候,会进入不同的执行环境,这些不同的执行环境就构成了执行环境栈。

  JavaScript中主要存在三种执行环境:

  • 全局执行环境

   JavaScript代码执行的默认环境。通常被默认为window对象,所有的全局变量和函数都作为window对象的属性和方法存在。当执行环境中的代码执行完毕之后,执行环境被销毁,其中的所有变量和函数也随之销毁。对于全局执行环境来说,当关闭网页或浏览器时,该环境被销毁。

  • 函数执行环境

     当执行一个JavaScript函数时,函数的环境被推入环境栈中,执行完毕之后,栈将执行环境推出,将控制权转交给之前的执行环境。

  • Eval环境

   执行eval()函数时创建。

  对于执行环境栈,请看如下代码:

var a = "global";
function example(){
console.log(a);
} function outer(){
var b = "outer";
console.log(b); function inner(){
var c = "inner";
console.log(c);
example();
} inner();
} outer();

  代码首先进入全局执行环境,然后依次进入outer,inner和example的执行环境,执行环境栈可以表示为:

  

  每个执行环境都有三个重要的属性,变量对象(VO)、作用域链(scope chain)和this。下面首先看一下变量对象。

  变量对象和活动对象(VO和AO)

   变量对象

  每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。当代码在一个环境中执行时,会创建当前变量对象的一个作用域链(scope chain)。作用域链的最前端,始终是当前执行环境的变量对象。如果执行环境是函数,则其活动对象(activation object)作为变量对象。作用域链的下一个变量对象来自于父执行环境,而再下一个变量对象来自于父环境的外部环境,以此类推构成完整的作用域链,而最外层的变量对象始终是全局执行环境的变量对象。

  一般来说,变量对象(VO)中包含以下信息:

  • 变量
  • 函数声明
  • 函数的形参

  当JavaScript代码执行的时候,如果试图寻找一个变量或函数,就会首先寻找VO。对于前面提到的代码,全局执行环境的VO如下所示:

  

  对于VO来说,函数表达式不包含在VO中,没有使用var声明的变量也不包含在VO中,这种方式只是给Global添加了一个属性。

  活动对象

  只有全局执行环境的变量对象允许通过VO的属性名称间接访问。但在函数执行环境中,VO是不允许被直接访问的。此时,由活动对象(Activation Object,简称AO)扮演VO的角色。活动对象在进入函数执行环境时被创建,它通过函数的arguments属性初始化,其中Arguments Objects是函数执行环境中活动对象AO的内部对象。

  VO和AO的关系,简单点说就是,VO在不同的执行环境中有不同的变现形式。在全局执行环境中,可以直接使用VO;但是在函数执行环境中,AO被创建。

  在上面的代码例子中,当开始执行outer函数的时候,outer函数的AO被创建如下图所示:

  

  执行环境的具体过程

  当进入一个执行环境的时候,JavaScript解释器会创建新的执行环境,但具体是怎么做的呢?主要分为两个阶段:

  • 创建阶段

    • 创建作用域链
    • 创建VO/AO
    • 设置this的值
  • 执行阶段
    • 设置变量的值
    • 设置函数的引用
    • 解释执行代码

  对于"创建VO/AO"这一步,JavaScript解释器主要做了下面的事情:

  • 根据函数参数,创建并初始化arguments object
  • 根据函数内部代码查找函数声明
    • 对于找到的所有函数声明,将函数名和引用全部存入VO/AO
    • 如果存在同名函数,进行覆盖
  • 根据函数内部代码查找变量声明
    • 对于找到的所有变量声明,全部存入VO/AO,并初始化为"undefined"
    • 如果变量名称和已经声明的形参或函数相同,那么变量声明不会干扰这类属性

  看下面的例子:

function example(p) {
var a = 'hello';
var b = function b() {...};
function c() {...}
} example(2);

  对于上面的例子,在执行环境创建阶段,会得到如下的执行环境对象:

exampleExecutionContext={
scopeChain: {...},
VO:{
arguments:{
0:2,
length:1
}
p:2,
c:pointer to function c()
a:undefined,
b:undefined
}, this: {...}
}

  在代码执行阶段,环境对象会被更新,如下所示:

exampleExecutionContext={
scopeChain: {...},
VO:{
arguments:{
0:2,
length:1
}
p:2,
c:pointer to function c()
a:'hello',
b:pointer to function b()
}, this: {...}
}

JavaScript执行环境的更多相关文章

  1. javascript执行环境(执行期上下文)详解

    javascript执行环境(执行期上下文) 当js控制器(control)进入可执行代码时,控制器会进入一个执行环境,活动的多个执行环境构成执行环境栈,最上面的是正在运行的执行环境,当控制器进入一个 ...

  2. JavaScript 执行环境、作用域、内存管理及垃圾回收机制

    前言 JavaScript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存. [原理]找出那些不再继续使用的变量,然后释放其占用的内存.为此,垃圾收集器会按照固定的时间间隔( ...

  3. Javascript 执行环境及作用域

    执行环境是javascript中最为重要的一个概念. 执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为. 每个执行环境都有一个与之关联的变量对象(variable object),环境 ...

  4. 【原】javascript执行环境及作用域

    最近在重读<javascript高级程序设计3>,觉得应该写一些博客记录一下学习的一些知识,不然都忘光啦.今天要总结的是js执行环境和作用域. 首先来说一下执行环境 一.执行环境 书上概念 ...

  5. 图解JavaScript执行环境结构

    JavaScript引擎在开始编译代码的时候,会对JavaScript代码进行一次预编译,生成一个执行环境,比如如下代码: window.onload=function(){ function sub ...

  6. DOM笔记(八):JavaScript执行环境和垃圾收集

    一.执行环境 在有关于JavaScript对象或者this的指向问题时,脱离不了的另外一个概念就是执行环境,即上下文环境.执行环境在JavaScript是一个 很重要的概念,因为它定义了变量或函数有权 ...

  7. javascript 执行环境,变量对象,作用域链

    前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体. 通过上网查资料,特来总结,以备回顾和修正. 要讲的依次为: EC( ...

  8. JavaScript 执行环境(执行上下文) 变量对象 作用域链 上下文 块级作用域 私有变量和特权方法

    总结自<高程三>第四章  理解Javascript_12_执行模型浅析   JS的执行环境与作用域  javascript高级程序第三版学习笔记[执行环境.作用域] 在javascript ...

  9. JavaScript——执行环境、变量对象、作用域链

    前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体.通过上网查资料,特来总结,以备回顾和修正. 目录: EC(执行环境或 ...

随机推荐

  1. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  2. s:form标签

    2017-01-07 17:43:18 基本的用法 <!-- Action类必须有一个无参的构造器,因为在执行action方法之前,拦截器已经创建了一个"空"的Action对 ...

  3. 我的MYSQL学习心得(三) 查看字段长度

    我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  4. 最牛的打字效果JS插件 typing.js

    最新在做公司的一个项目,需要实现一个敲打代码的动画效果,粗意味比较简单,果断自己直接开写,写着写着发现是一个坑.需要支持语法高亮,并不能直接简单的用setTimeout来动态附件innerHTML.苦 ...

  5. Building the Testing Pipeline

    This essay is a part of my knowledge sharing session slides which are shared for development and qua ...

  6. ASP.NET Web API WebHost宿主环境中管道、路由

    ASP.NET Web API WebHost宿主环境中管道.路由 前言 上篇中说到ASP.NET Web API框架在SelfHost环境中管道.路由的一个形态,本篇就来说明一下在WebHost环境 ...

  7. ecshop 模板开发总结

    ecshop 模板开发总结 模板标签 1.{$articleTitle|escape:"html"} 描述:用于html转码,url转码,在没有转码的变量上转换单引号,十六进制转码 ...

  8. CentOS 6.8 安装TigerVNC 实现 Linux 远程桌面

    CentOS 6.8 有默认的安装的 vnc 位于端口 5900 : 系统->首选项->远程桌面 勾选[共享]的选项,  取消勾选[安全]的选项, 然后防火墙添加 5900 端口 基本就可 ...

  9. es6学习笔记

    class Point { constructor(x, y) { this.x = x; this.y = y; } static classMethod() { console.log('fath ...

  10. 大数据时代下的SQL Server第三方负载均衡方案----Moebius测试

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 架构原理(Architecture) 测试环境(Environment) 安装Moebius( ...