JavaScript变量对象其二:VO在不同的执行上下文中
2011-05-08 00:00
786 查看
不同执行上下文中的变量对象
对于所有类型的执行上下文来说,变量对象的一些操作(如变量初始化)和行为都是共通的。从这个角度来看,把变量对象作为抽象的基本事物来理解更为容易。同样在函数上下文中也定义和变量对象相关的额外内容。抽象变量对象VO (变量初始化过程的一般行为) ║ ╠══> 全局上下文变量对象GlobalContextVO ║ (VO === this === global) ║ ╚══> 函数上下文变量对象FunctionContextVO (VO === AO, 并且添加了<arguments>和<formal parameters>)
我们来详细看一下:
全局上下文中的变量对象
首先,我们要给全局对象一个明确的定义:全局对象(Global object) 是在进入任何执行上下文之前就已经创建了的对象。这个对象只存在一份,它的属性在程序中任何地方都可以访问,全局对象的生命周期终止于程序退出那一刻。
全局对象初始创建阶段将Math、String、Date、parseInt作为自身属性,等属性初始化,同样也可以有额外创建的其它对象作为属性(其可以指向到全局对象自身)。例如,在DOM中,全局对象的window属性就可以引用全局对象自身(当然,并不是所有的具体实现都是这样):
global = { Math: , String: ... ... window: global //引用自身 };
当访问全局对象的属性时通常会忽略掉前缀,这是因为全局对象是不能通过名称直接访问的。不过我们依然可以通过全局上下文的this来访问全局对象,同样也可以递归引用自身。例如,DOM中的window。综上所述,代码可以简写为:
String(10); // 就是global.String(10); // 带有前缀 window.a = 10; // === global.window.a = 10 === global.a = 10; this.b = 20; // global.b = 20;
因此,回到全局上下文中的变量对象——在这里,变量对象就是全局对象自己:
VO(globalContext) === global;
非常有必要要理解上述结论,基于这个原理,在全局上下文中声明的对应,我们才可以间接通过全局对象的属性来访问它(例如,事先不知道变量名称)。
var a = new String('test'); alert(a); // 直接访问,在VO(globalContext)里找到:"test" alert(window['a']); // 间接通过global访问:global === VO(globalContext): "test" alert(a === this.a); // true var aKey = 'a'; alert(window[aKey]); // 间接通过动态属性名称访问:"test"
函数上下文中的变量对象
在函数执行上下文中,VO是不能直接访问的,此时由活动对象(activation object,缩写为AO)扮演VO的角色。VO(functionContext) === AO;
活动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。arguments属性的值是Arguments对象:
AO = { arguments: <ArgO> };
Arguments对象是活动对象的一个属性,它包括如下属性:
callee — 指向当前函数的引用
length — 真正传递的参数个数
properties-indexes (字符串类型的整数) 属性的值就是函数的参数值(按参数列表从左到右排列)。 properties-indexes内部元素的个数等于arguments.length. properties-indexes 的值和实际传递进来的参数之间是共享的。
例如:
function foo(x, y, z) { // 声明的函数参数数量arguments (x, y, z) alert(foo.length); // 3 // 真正传进来的参数个数(only x, y) alert(arguments.length); // 2 // 参数的callee是函数自身 alert(arguments.callee === foo); // true // 参数共享 alert(x === arguments[0]); // true alert(x); // 10 arguments[0] = 20; alert(x); // 20 x = 30; alert(arguments[0]); // 30 // 不过,没有传进来的参数z,和参数的第3个索引值是不共享的 z = 40; alert(arguments[2]); // undefined arguments[2] = 50; alert(z); // 40 } foo(10, 20);
这个例子的代码,在当前版本的Google Chrome浏览器里有一个bug — 即使没有传递参数z,z和arguments[2]仍然是共享的。
延伸阅读
此文章所在专题列表如下:我们应该如何去了解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闭包其三:闭包的用法
相关文章推荐
- 谈谈自己对js闭包,执行上下文,作用域链,活动对象AO,变量对象VO的理解
- JavaScript变量对象其三:执行上下文的两个阶段
- JS执行上下文与变量对象
- 关于javascript中的 执行上下文和对象变量
- JavaScript核心:对象 原型链 构造函数 执行上下文栈 执行上下文 变量对象 活动对象 作用域链 闭包 This 总结
- javascript this 和执行上下文 之大不同
- JavaScript变量对象、执行环境和作用域链
- 深入学习JS执行--创建执行上下文(变量对象,作用域链,this)
- 阿里TTL异步执行上下文对象传递
- 执行上下文中的变量对象和活动对象
- 执行环境和对象上下文
- 透过一道面试题来探探JavaScript中执行上下文和变量对象的底
- EF 中不同会话上下文的对象,不能互设为对方的导航属性值
- js执行上下文补充 变量对象 (看汤姆大叔博客所记)
- 透过一道面试题来探探JavaScript中执行上下文和变量对象的底
- JavaScript的执行上下文(与上下文不同,此点常被混淆)
- JavaScript delete用法,属性,特性,执行上下文,激活对象 综合篇
- js笔记---作用域(执行上下文[execution context],活动对象) 闭包
- js笔记---作用域(执行上下文[execution context],活动对象) 闭包
- javascript this 和执行上下文 之大不同