JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么?
大多数ECMAScript程序员应该都知道变量与执行上下文有密切关系:
var a = 10; // 全局上下文中的变量 (function () { var b = 20; // function上下文中的局部变量 })(); alert(a); // 10 alert(b); // 全局变量 "b" 没有声明
并且,很多程序员也都知道,当前ECMAScript规范指出独立作用域只能通过“函数(function)”代码类型的执行上下文创建。也就是说,相对于C/C++来说,ECMAScript里的for循环并不能创建一个局部的上下文。
for (var k in {a: 1, b: 2}) { alert(k); } alert(k); // 尽管循环已经结束但变量k依然在当前作用域
我们来看看一下,我们声明数据的时候到底都发现了什么细节。
数据声明
如果变量与执行上下文相关,那变量自己应该知道它的数据存储在哪里,并且知道如何访问。这种机制称为变量对象(variable object)。
变量对象(缩写为VO)是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:
- 变量 (var, 变量声明);
- 函数声明 (FunctionDeclaration, 缩写为FD);
- 函数的形参
举例来说,我们可以用普通的ECMAScript对象来表示一个变量对象:
VO = {};
就像我们所说的, VO就是执行上下文的属性(property):
activeExecutionContext = { VO: { // 上下文数据(var, FD, function arguments) } };
只有全局上下文的变量对象允许通过VO的属性名称来间接访问(因为在全局上下文里,全局对象自身就是变量对象,稍后会详细介绍),在其它上下文中是不能直接访问VO对象的,因为它只是内部机制的一个实现。
当我们声明一个变量或一个函数的时候,和我们创建VO新属性的时候一样没有别的区别(即:有名称以及对应的值)。例如:
var a = 10; function test(x) { var b = 20; }; test(30);
对应的变量对象是:
// 全局上下文的变量对象 VO(globalContext) = { a: 10, test: <reference to function> }; // test函数上下文的变量对象 VO(test functionContext) = { x: 30, b: 20 };
在具体实现层面(以及规范中)变量对象只是一个抽象概念。(从本质上说,在具体执行上下文中,VO名称是不一样的,并且初始结构也不一样。
延伸阅读
此文章所在专题列表如下:
- 我们应该如何去了解JavaScript引擎的工作原理
- JavaScript探秘:编写可维护的代码的重要性
- JavaScript探秘:谨慎使用全局变量
- JavaScript探秘:var预解析与副作用
- JavaScript探秘:for循环(for Loops)
- JavaScript探秘:for-in循环(for-in Loops)
- JavaScript探秘:Prototypes强大过头了
- JavaScript探秘:eval()是“魔鬼”
- JavaScript探秘:用parseInt()进行数值转换
- JavaScript探秘:基本编码规范
- JavaScript探秘:函数声明与函数表达式
- JavaScript探秘:命名函数表达式
- JavaScript探秘:调试器中的函数名
- JavaScript探秘:JScript的Bug
- JavaScript探秘:JScript的内存管理
- JavaScript探秘:SpiderMonkey的怪癖
- JavaScript探秘:命名函数表达式替代方案
- JavaScript探秘:对象Object
- JavaScript探秘:原型链 Prototype chain
- JavaScript探秘:构造函数 Constructor
- JavaScript探秘:可执行的上下文堆栈
- 执行上下文其一:变量对象与活动对象
- 执行上下文其二:作用域链 Scope Chains
- 执行上下文其三:闭包 Closures
- 执行上下文其四:This指针
- JavaScript探秘:强大的原型和原型链
- JavaScript函数其一:函数声明
- JavaScript函数其二:函数表达式
- JavaScript函数其三:分组中的函数表达式
- JavaScript函数其四:函数构造器
- JavaScript变量对象其一:VO的声明
- JavaScript变量对象其二:VO在不同的执行上下文中
- JavaScript变量对象其三:执行上下文的两个阶段
- JavaScript变量对象其四:关于变量
- JavaScript变量对象其五:__parent__ 属性
- JavaScript作用域链其一:作用域链定义
- JavaScript作用域链其二:函数的生命周期
- JavaScript作用域链其三:作用域链特征
- JavaScript闭包其一:闭包概论
- JavaScript闭包其二:闭包的实现
- JavaScript闭包其三:闭包的用法
本文地址:http://www.nowamagic.net/librarys/veda/detail/1670,欢迎访问原出处。
大家都在看