JavaScript高级程序设计(第2版) 之 JavaScript变量作用域
相关概念
执行环境、变量对象、作用域链
执行环境定义了变量或者函数可访问的其他数据。就像如下代码:
Var r = ‘2011-7-26’;
Function show()
{
Var t = r;
Alert(t);
}
Show();
包含一个全局的执行环境,还包含一个函数级别的执行环境。其实每一个执行环境都有一个与之关联的变量对象以存储可以访问到的对象。这个关联的对象是代码不可访问的,但是它对我们的变量作用范围起到了很重要的作用。
如上代码包含一个全局的变量对象(别名A),一个show范围的变量对象(别名B)
其中A存储了r、 show两个对象, B存储了t仅一个对象(如果arguments不空则包含)。
在代码的执行过程中还涉及到了作用域链的概念,它是一个栈结构,以后进先出的形式存储执行环境中相关联的变量对象。在查找对象的声明时是自顶向下搜索的,所以在这个过程中出现了局部变量会覆盖全局变量的现象,因为在搜索的过程中只要找到一个声明就返回了,不会继续向深处搜索。
如上代码:
首先会把A存储在栈中, 然后把B压入栈顶;在show函数内部涉及到了A中的r变量,它的搜索过程是从栈顶向下搜索的,直到在A中发现了r的声明。倘若B中也声明了r,那么我们得到的就是局部变量中的r了。
在javascript中我们经常会用with简化一些代码的写法。其实它是根据with中的对象产生了一个变量对象(包含对象的所有方法、属性,类似做了声明),放入了并且放入了栈顶,这样我们就可以直接访问对象的属性了(而不用特别指定对象名称了)
注:
在javascript中并不包含所谓的块属性(花括号区域),当我们在块中声明变量、方法时,它会自动的把属性、方法添加到最近的执行环境变量中。如下:
Function show()
{
Var name = ‘tom’;
{
Var age = 12;
}
Alert(age);
}
Show(); //12
可见age和name的作用范围是相同的。在我们的代码中更多的情况是如下用法:
For(var i=0; i<10; i++){}
Alert(i); // 10
注意:此时已经是10了, 不像其他语言离开了花括号变量就会销毁。