asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0
     我们可能注意到了,javascript的变量和对象的属性之间有很多的相似点。例如,它们采用相同的赋值方式,而且在j表达式中的用法也相同,等等。那么变量i和对象o的属性i之间有什么根本的区别吗?答案是没有。在js中变量基本上和对象的属性是一样的。
     当js的解释器开始运行时,它首先要做的事情之一就是执行任何js代码之前,创建一个全局对象(gloal object)。这个对象的属性就是js程序的全局变量。当声明一个js全局变量时,实际上所做的事定义了那个全局对象的一个属性。
    此外,js解释器还会用预定义的值和函数来初始化全局对象的许多属性。例如,属性Infinity、parseInt和Math分别引用了数值Infinity、预定义的函数parseInt()和预定义的对象Math。
     在程序的顶层代码中(例如,不属于函数的js代码),你可以使用js的关键字this来引用这个全局对象。在函数内部,this则有别的用途。
     在客户端js中,window对象代表游览窗口,它是包含在该窗口中的所有js代码的全局对象。这个全局window对象具有自我引用的window属性,它代替了this属性,可以用来引用这个全局对象。window对象定义了全局的核心属性,如parseInt和Math,此外它还定义了全局的客户端属性,如navigator和screen.
     如果全局变量时特殊的全局对象的属性,那么局部变量又是什么呢?它们也是一个对象的属性,这个对象被称为调用对象(call object)。虽然调用对象的生命周期比全局对象短,但是它们的用途是相同的。在执行一个函数时,函数的参数和局部变量是作为调用对象的属性而存储的。用一个完全独立的对象来存储局部变量使js可以防止局部变量覆盖同名的全局变量的值。
     js的解释器每次开始执行一个函数时,都会为那个函数创建一个执行环境(execution context)。显然,一个执行环境就是所有js代码段执行时所在环境。这个环境的一个重要部分是定义变量的对象。因此,运行不属于任何函数的js代码的环境使用的是全局对象。所有js函数都运行在自己独有的执行环境中,而且具有自己的调用对象,在调用对象中定义了局部变量。
    要注意一个有趣的地方,js的实现允许有多个全局执行环境,每个执行环境有不同的全局对象(但是,在这种情况下,每个全局对象就不完全是全局了)。一个显而易见的例子是,客户端js的每个独立的游览窗口或同一窗口的不同框架中都定义了独立的全局执行环境。每个框架或窗口中的客户端js代码都运行在自己的执行环境中,具有自己的全局对象。但是,这些独立的客户端全局对象具有将与其他对象彼此连接起来的属性。因此,一个框架中js代码可以使用表示式parent.frames[1]来引用另一个框架中的js代码,在第2个框架中的代码可以使用表达式parent.frames[0].x来引用第一个框架中的全局变量x。一个js解释器可以在不同的全局执行环境运行脚本,而且这些环境之间并不完全脱节的,它们彼此可以相互引用。
    最后一点需要额外说明一下。如果一个执行环境中的js代码可以读写另一个执行环境中定义的属性,并且执行它的函数,那么复杂度就上升了一层,我们需要考虑安全性的问题了。以客户端js为例。假设游览窗口a正在运行一个脚本或者它含有来自局域网的信息,而窗口b则正在运行来自inernet的某个站点的脚本。一般来说,我们不希望窗口b中的代码能访问a的属性。如果允许这样做,那么它可能就读取公司的机密信息并窃取这些信息。所以,为了安全地运行js代码,必须有一定的安全机制。当从一个执行环境访问另一个执行环境时,如果这种访问是不允许的,那么就禁止执行它。
    全局变量具有全局的作用域,而函数zhog声明的变量具有局部的作用域。如果一个函数定义嵌套在另一个函数中,那么在嵌套的函数中声明的变量具有嵌套的局部作用域。既然我们知道全局变量是全局对象的属性,而局部变量是一个特殊的调用对象的属性,那么我们可以再次关注一下变量作用域的表示法,对于它进行再定义。有关作用域的新描述给理解多环境下的变量提供了一种有用的方法,它为js的工作过程提供了一种强大的、新的理解。
    每个js执行环境都有一个和它关联在一起的作用域链(scope chain)。这个作用域链式一个对象列表或对象链。当js代码需要查询变量x的值时(一个称为变量名解析variable name resolution的过程),它就开始查看该链的第一个对象。如果那个对象有一个名为x的属性,那么就采用那个属性的值。如果第一个对象没有名为x的属性,js就会继续查询链中的第2个对象。如果第2个对象仍然没有名为x的属性那么就继续查询下一个对象,直到到达全局对象为止。
     在js的顶层代码中(例如,不属于任何函数定义的代码),作用域链只由一个对象构成,那就是全局对象。所有变量都是在这个对象中查询。如果一个变量并不存在,那么这个变量的值就是为定义。在一个(非嵌套的)函数中,作用域链由两个对象构成,第一个是函数的调用对象,第二个就是全局对象。当函数引用一个变量时,首先检查的是调用对象(局部作用域),其次才检查全局对象(全局作用域)。在一个嵌套函数的作用域链中可以有三个或更多的对象。
posted on 2008-03-24 09:23 汪杰 阅读(346) 评论(0)  编辑 收藏 引用 所属分类: javascript
只有注册用户登录后才能发表评论。

<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 457542
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜