JavaScript的深入理解:变量对象(Variable Object)
通常,各类文章和javascript相关的书籍都声称:“不管是使用var关键字(在全局上下文)还是不使用var关键字(在任何地方),都可以声明一个变量”。请记住,这是错误的概念:
任何时候,变量只能通过使用var关键字才能声明。
1.全局对象的属性
下面的赋值语句:
a = 10;
1
这仅仅是给全局对象创建了一个新属性(但它不是变量)。“不是变量”并不是说它不能被改变,而是指它不符合ecmascript规范中的变量概念,所以它“不是变量”(它之所以能成为全局对象的属性,完全是因为vo(globalcontext) === global,大家还记得这个吧?)。
让我们通过下面的实例看看具体的区别吧:
alert(a); // undefined
alert(b); // "b" 没有声明
b = 10;
var a = 20;
所有根源仍然是vo和进入上下文阶段和代码执行阶段:
进入上下文阶段:
vo = {
a: undefined
};
我们可以看到,因为“b”不是一个变量,所以在这个阶段根本就没有“b”,“b”将只在代码执行阶段才会出现(但是在我们这个例子里,还没有到那就已经出错了)。
让我们改变一下例子代码:
alert(a); // undefined, 这个大家都知道,
b = 10;
alert(b); // 10, 代码执行阶段创建
var a = 20;
alert(a); // 20, 代码执行阶段修改
2.delete属性
关于变量,还有一个重要的知识点。变量相对于简单属性来说,变量有一个特性(attribute):{dontdelete},这个特性的含义就是不能用delete操作符直接删除变量属性。
a = 10;
alert(window.a); // 10
alert(delete a); // true
alert(window.a); // undefined
var b = 20;
alert(window.b); // 20
alert(delete b); // false
alert(window.b); // still 20
但是这个规则在有个上下文里不起走样,那就是eval上下文,变量没有{dontdelete}特性。
eval('var a = 10;');
alert(window.a); // 10
alert(delete a); // true
alert(window.a); // undefined
3.活动对象的访问
特殊实现: _parent_ 属性
前面已经提到过,按标准规范,活动对象是不可能被直接访问到的。但是,一些具体实现并没有完全遵守这个规定,例如spidermonkey和rhino;的实现中,函数有一个特殊的属性 parent,通过这个属性可以直接引用到活动对象(或全局变量对象),在此对象里创建了函数。
例如 (spidermonkey, rhino):
var global = this;
var a = 10;
function foo() {}
alert(foo.__parent__); // global
var vo = foo.__parent__;
alert(vo.a); // 10
alert(vo === global); // true
在上面的例子中我们可以看到,函数foo是在全局上下文中创建的,所以属性parent 指向全局上下文的变量对象,即全局对象。
然而,在spidermonkey中用同样的方式访问活动对象是不可能的:在不同版本的spidermonkey中,内部函数的parent 有时指向null ,有时指向全局对象。
在rhino中,用同样的方式访问活动对象是完全可以的。
例如 (rhino):
var global = this;
var x = 10;
(function foo() {
var y = 20;
// "foo"上下文里的活动对象
var ao = (function () {}).__parent__;
print(ao.y); // 20
// 当前活动对象的__parent__ 是已经存在的全局对象
// 变量对象的特殊链形成了
// 所以我们叫做作用域链
print(ao.__parent__ === global); // true
print(ao.__parent__.x); // 10
})();
上一篇: 四种按摩减肥方法 脚部按摩旋揉肚脐周围
下一篇: 揭秘曹操爱将于禁,晚年为何会抑郁而死?
推荐阅读
-
深入理解JavaScript中的对象复制(Object Clone)_基础知识
-
深入理解JavaScript创建对象的多种方式以及优缺点
-
深入理解JavaScript中的对象复制(Object Clone)
-
深入理解JavaScript中的块级作用域、私有变量与模块模式
-
深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域
-
深入理解JavaScript中的对象
-
JavaScript的深入理解:变量对象(Variable Object)
-
深入理解JavaScript中的对象复制(Object Clone)
-
深入理解JavaScript中的块级作用域、私有变量与模块模式
-
深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域