执行上下文的代码被分成两个基本的阶段来处理:

  1. 进入执行上下文
  2. 执行代码

变量对象的修改变化与这两个阶段紧密相关。

注:这2个阶段的处理是一般行为,和上下文的类型无关(也就是说,在全局上下文和函数上下文中的表现是一样的)。

进入执行上下文

当进入执行上下文(代码执行之前)时,VO里已经包含了下列属性(前面已经说了):

  • 函数的所有形参(如果我们是在函数执行上下文中) — 由名称和对应值组成的一个变量对象的属性被创建;没有传递对应参数的话,那么由名称和undefined值组成的一种变量对象的属性也将被创建。
  • 所有函数声明(FunctionDeclaration, FD) —由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建;如果变量对象已经存在相同名称的属性,则完全替换这个属性。
  • 所有变量声明(var, VariableDeclaration) — 由名称和对应值(undefined)组成一个变量对象的属性被创建;如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。

让我们看一个例子:

function test(a, b) {
var c = 10;
function d() {}
var e = function _e() {};
(function x() {});
} test(10); // call

当进入带有参数10的test函数上下文时,AO表现为如下:

AO(test) = {
a: 10,
b: undefined,
c: undefined,
d: <reference to FunctionDeclaration "d">
e: undefined
};

注意,AO里并不包含函数“x”。这是因为“x” 是一个函数表达式(FunctionExpression, 缩写为 FE) 而不是函数声明,函数表达式不会影响VO。 不管怎样,函数“_e” 同样也是函数表达式,但是就像我们下面将看到的那样,因为它分配给了变量 “e”,所以它可以通过名称“e”来访问。 函数声明FunctionDeclaration与函数表达式FunctionExpression 的不同,可以参考前面的专题文章。

这之后,将进入处理上下文代码的第二个阶段 — 执行代码。

代码执行

这个周期内,AO/VO已经拥有了属性(不过,并不是所有的属性都有值,大部分属性的值还是系统默认的初始值undefined )。还是前面那个例子,AO/VO在代码解释期间被修改如下:

AO['c'] = 10;
AO['e'] = <reference to FunctionExpression "_e">;

再次注意,因为FunctionExpression“_e”保存到了已声明的变量“e”上,所以它仍然存在于内存中。而FunctionExpression “x”却不存在于AO/VO中,也就是说如果我们想尝试调用“x”函数,不管在函数定义之前还是之后,都会出现一个错误“x is not defined”,未保存的函数表达式只有在它自己的定义或递归中才能被调用。

另一个经典例子:

alert(x); // function

var x = 10;
alert(x); // x = 20;
function x() {}; alert(x); //

为什么第一个alert “x” 的返回值是function,而且它还是在“x” 声明之前访问的“x” 的?为什么不是10或20呢?因为,根据规范函数声明是在当进入上下文时填入的; 同意周期,在进入上下文的时候还有一个变量声明“x”,那么正如我们在上一个阶段所说,变量声明在顺序上跟在函数声明和形式参数声明之后,而且在这个进入上下文阶段,变量声明不会干扰VO中已经存在的同名函数声明或形式参数声明,因此,在进入上下文时,VO的结构如下:

VO = {};

VO['x'] = <reference to FunctionDeclaration "x">

// 找到var x = 10;
// 如果function "x"没有已经声明的话
// 这时候"x"的值应该是undefined
// 但是这个case里变量声明没有影响同名的function的值 VO['x'] = <the value is not disturbed, still function>

紧接着,在执行代码阶段,VO做如下修改:

VO['x'] = 10;
VO['x'] = 20;

我们可以在第二、三个alert看到这个效果。

在下面的例子里我们可以再次看到,变量是在进入上下文阶段放入VO中的。(因为,虽然else部分代码永远不会执行,但是不管怎样,变量“b”仍然存在于VO中。)

if (true) {
var a = 1;
} else {
var b = 2;
} alert(a); //
alert(b); // undefined,不是b没有声明,而是b的值是undefined

(Mark)JS中的上下文的更多相关文章

  1. JS 中 this上下文对象的使用方式

    JavaScript 有一套完全不同于其它语言的对 this 的处理机制. 在五种不同的情况下 ,this 指向的各不相同. 有句话说得很在理 -- 谁调用它,this就指向谁 一.全局范围内 在全局 ...

  2. 进阶学习js中的执行上下文

    在js中的执行上下文,菜鸟入门基础 这篇文章中我们简单的讲解了js中的上下文,今天我们就更进一步的讲解js中的执行上下文. 1.当遇到变量名和函数名相同的问题. var a = 10; functio ...

  3. 第22篇 js中的this指针的用法

    前面把js的相关知识总结了下,今天把js中的上下文的this,对于强类型语言,this的用法非常的单一,因为他们没有js特有的动态绑定. 首先看下面代码: function funcA() { thi ...

  4. js中当call或者apply传入的第一个参数是null/undefined时,js函数内执行的上下文环境是什么?

    在js中我们都知道call/apply,还有比较少用的bind;传入的第一个参数都是改变函数当前上下文对象; call/apply区别在于传的参数不同,一个是已逗号分隔字符串,一个以数组形式.而bin ...

  5. js中的执行上下文,菜鸟入门基础。

    console.log(a); //Uncaught ReferenceError: a is not defined 因为没有定义a所以报错了. var a = 52; console.log(a) ...

  6. JS与OC交互,JS中调用OC方法(获取JSContext的方式)

    最近用到JS和OC原生方法调用的问题,查了许多资料都语焉不详,自己记录一下吧,如果有误欢迎联系我指出. JS中调用OC方法有三种方式: 1.通过获取JSContext的方式直接调用OC方法 2.通过继 ...

  7. 深入理解Node.js中的垃圾回收和内存泄漏的捕获

    深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...

  8. 关于js中的this

    关于js中的this this是javascript中一个很特别的关键字,也是一种很复杂的机制,学习this的第一步就是要明白this既不指向函数自身也不指向函数的词法作用域,this实际上是函数被调 ...

  9. JS中 call() 与apply 方法

    1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...

随机推荐

  1. HTML综合实例【月福首页】

    1. 首页的布局结构 2. 排版的准备工作 网站的素材:与当前网页放在一起. 创建一个html文件,来进行排版. 网页的背景色 确定主页的宽度:778px 3. HTML注释 <!-- 注释内容 ...

  2. 从LFS官方文档构建完整Linux系统

    从LFS官方文档构建完整Linux系统 http://www.cnblogs.com/sonofdark/p/4962609.html 这不是新手教程!!! Parallels Desktop (为防 ...

  3. HDU 6188 Duizi and Shunzi 贪心

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6188 题意:给了n个数,然后现在问我们最多构成多少个对子和顺子,其中对子是2个相同的牌,顺子是3个连续 ...

  4. HDU 6186 CS Course 前缀和,后缀和

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6186 题意:给了n个数,然后有q个查询,每个查询要求我们删掉一个数,问删掉这个数后整个序列的与值,或值 ...

  5. HDU 5627 Clarke and MST &意义下最大生成树 贪心

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5627 题意:Bestcoder的一道题,让你求&意义下的最大生成树. 解法: 贪心,我们从高位 ...

  6. PHP常用函数总结(180多个)

    PHP常用函数总结 数学函数 1.abs(): 求绝对值 $abs = abs(-4.2); //4.2 数字绝对值数字 2.ceil(): 进一法取整 echo ceil(9.999); // 10 ...

  7. 部署Nginx

    部署Nginx #下载nginx wget http://nginx.org/download/nginx-1.12.2.tar.gz#安装依赖 yum install pcre-devel open ...

  8. hdu 2883(构图+最大流+压缩区间)

    kebab Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. 解决网页中Waiting (TTFB)数据加载过慢的问题

    解决网页中Waiting (TTFB)数据加载过慢的问题 最近做了一个网页,在本地测试良好,数据可以得到很快的反馈,但是当部署到云端Linux上时候,就会出现加载缓慢的问题.本地测试,得到数据大概3s ...

  10. CentOS7英文环境下使用中文输入法

    一般我们使用英文环境是没有办法使用中文的,这是因为我们没有设置在英文环境下的中文配置,下面我们在英文环境下配置中文输入法ibus使得我们可以输入中文. 首先,安装ibus(centos6以后已经默认安 ...