Variable Object
在ECMAScipt中,通过变量对象Variable Object (VO)机制来存贮、访问变量variables。VO中包含了:
1. variables (通过var 声明的变量)
2. function declaration (函数声明)
3. function formal parameters (函数行参)
注: 不包括function expression (函数表达式)。
Variable Object在Global Context中等同于Global Object,在Function Context中称为Activation Object (AO),
一般来讲,Variable Object / Activation Object 我们不能直接在外部访问到。
要访问某个变量x,首先在x所在Function Context中的Variable Object中查找,
若找不到,则在x所属function的[[scope]]属性中保存的scope chain中,
逐级向上查找,直至查找到Global Object,如果仍未找到则返回 x is not defined 。
我们所常见的window
对象实际上是Global Object的引用,所以通过var
在Global Context中声明的变量x,
可以通过x直接访问,也可通过window.x
来间接访问,并且通过window.x
访问比直接访问要慢 。
var a = "variable";
b = "property";
console.log(window.a); // "variable"
console.log(window.b); // "property"
delete window.a; // false
console.log(window.a); // "variable"
delete window.b; //true
console.log(window.b); //undefined;
在上面的例子中, 虽然都能通过window.a
, window.b
的形式来访问,看似都是window
的属性,但是实质是不同的。
不使用var
声明的”变量“,实际不是真正的变量,而是Global Object的属性,可以通过delete 关键字删除,而真正的变量拥有DontDelete
属性,不能通过delete
删除。
但值得注意的是,在firebug中,执行
delete window.a; //true
delete window.b; //true
返回值都是true,这是由于在eval context中,变量不会被添加DontDelete
属性,firebug正是利用eval来执行我们在console中的代码,而在chrome,opera的console中则返回正确的false,true
参考
http://dmitrysoshnikov.com/ecmascript/chapter-2-variable-object
迁移自旧博客懒蜗牛