犀牛书第4章 变量(中篇)

来源:互联网 发布:php人事管理系统 编辑:程序博客网 时间:2024/05/21 11:01

在JavaScript中,变量基本上和对象的属性是一样的。

全局变量:全局对象

当JavaScript的解释器开始运行时,它首先要做的事情之一就是在执行任何JavaScript代码之前,创建一个全局对象。这个对象的属性就是JavaScript程序的全局变量。当声明一个JavaScript的全局变量时,实际上所做的是定义了那个全局对象的一个属性。此外JavaScript解释器还会用预定义的值和函数来初始化全局对象的许多属性。

在程序的顶层代码中(例如不属于函数的JavaScript代码),可以使用关键字this来引用这个全局对象。在函数内部,this则有别的用途,这个以后讨论。

在客户端JavaScript中,Window对象代表浏览器窗口,它是包含在该窗口中的所有JavaScript代码的全局对象。

局部变量:调用对象

如果全局变量是全局对象的属性,那么局部变量又是什么呢?它们也是一个对象的属性,这个对象被称为调用对象。在执行一个函数时,函数的参数和局部变量是作为调用对象的属性而存储的。用一个完全独立的对象来存储局部变量使JavaScript可以防止局部变量覆盖同名的全局变量的值。

JavaScript的执行环境

JavaScript解释器每次开始执行一个函数时,都会为那个函数创建一个执行环境。显然一个执行环境就是所有JavaScript代码段执行时所在的环境。这个环境的一个重要部分是定义变量的对象。因此运行不属于任何函数的JavaScript代码的环境使用的就是全局对象。所有JavaScript函数都运行在自己独有的执行环境中,而且具有自己的调用对象,在调用对象中定义了局部变量。

要注意的一个有趣的地方是,JavaScript的实现允许有多个全局执行环境,每个执行环境有不同的全局对象( 但是,在这种情况下,每个全局对象就不完全是全局的了)。一个显而易见的例子是,客户端JavaScript的每个独立的浏览器窗口或同一窗口的不同帧中都定义了独立的全局执行环境。每个帧或窗口中的客户端JavaScript代码都运行在自己的执行环境中,具有自己的全局对象。但是这些独立的客户端全局对象具有将与其他对象彼此连接起来的属性。因此一个帧中的JavsScript代码可以使用表达式parent.frames[1]来引用另一个帧中的JavaScript代码,在第二个帧中的代码可以使用表达式parent.frames[0].x来引用第一个帧中的全局变量x。

读者不必立刻完全理解独立的窗口和帧执行环境是如何链接在一起的。当讨论JavaScript和web浏览器的集成时会详细介绍这一主题。现在应该理解的是,JavaScript有很大的灵活性,一个JavaScript解释器可以在不同的全局执行环境中运行脚本,而且这些环境之间并不是完全脱节的,它们彼此可以相互引用。

最后一点需要额外说明一下,如果一个执行环境中的JavaScript代码可以读写另一个执行环境中定义的属性,并且执行它的函数,那么复杂度就上升了一层,我们需要考虑安全性的问题了。这里不讨论安全性的具体细节。所以为了安全地运行JavaScript代码,必须有一定的安全机制。当从一个执行环境访问另一个执行环境时,如果这种访问是不允许的,那么就禁止执行它。