热烈祝贺台州朗动科技的站长论坛隆重上线!(2012-05-28)    热烈庆祝伟大的祖国60周年生日 点击进来我们一起为她祝福吧(2009-09-26)    站长论坛禁止发布广告,一经发现立即删除。谢谢各位合作!.(2009-08-08)    热烈祝贺台州网址导航全面升级,全新版本上线!希望各位一如既往地支持台州网址导航的发展.(2009-03-28)    台州站长论坛恭祝各位新年快乐,牛年行大运!(2009-01-24)    台州Link正式更名为台州网址导航,专业做以台州网址为主的网址导航!(2008-05-23)    热烈祝贺台州Link资讯改名为中国站长资讯!希望在以后日子里得到大家的大力支持和帮助!(2008-04-10)    热烈祝贺台州Link论坛改名为台州站长论坛!希望大家继续支持和鼓励!(2008-04-10)    台州站长论坛原[社会琐碎]版块更名为[生活百科]版块!(2007-09-05)    特此通知:新台州站长论坛的数据信息全部升级成功!">特此通知:新台州站长论坛的数据信息全部升级成功!(2007-09-01)    台州站长论坛对未通过验证的会员进行合理的清除,请您谅解(2007-08-30)    台州网址导航|上网导航诚邀世界各地的网站友情链接和友谊联盟,共同引领网站导航、前进!(2007-08-30)    禁止发广告之类的帖,已发现立即删除!(2007-08-30)    希望各位上传与下载有用资源和最新信息(2007-08-30)    热烈祝贺台州站长论坛全面升级成功,全新上线!(2007-08-30)    
便民网址导航,轻松网上冲浪。
台州维博网络专业开发网站门户平台系统
您当前的位置: 首页 » JavaScript/JQuery编程 » JavaScript中的[[scope]]和Scope Chain

JavaScript中的[[scope]]和Scope Chain

论坛链接
  • JavaScript中的[[scope]]和Scope Chain
  • 发布时间:2009-09-07 16:28:21    浏览数:7495    发布者:superadmin    设置字体【   
ECMA262中规定JS使用Scope Chain来实现closure,Scope Chain是JS中非常重要的机制,JS中所有的标识符(Identifier)都是通过Scope Chain来查找值的。下面的部分是关于ECMA262及其实现SpiderMonkey和JScript如何用Scope Chain和[[scope]]来实现closure的。

变量标识符查找

当我们在JS程序里写下像a++这样的表达式时,很难想象a的值和内存地址经过了复杂的查找过程才得以确定,JS的所有标识符(通常是我们自己定义的变量名)在执行时都是从Scope Chain中查找值的,这也是导致JS执行速度低的原因和JS实现灵活的动态特性的基础。Scope Chain是一个链表,在JS执行时,总是维护着Scope Chain来保证变量的可访问性或者不可访问性。对于这个过程ECMA262给出了很明确的描述(我翻译了一下,各位将就着看):

1. 获取Scope Chain的下一个对象。如果没有对象了,则转到第5步。

2. 调用结果(1)的[[HasProperty]]方法, 传递Identifier作为参数

3. 如果结果(2)是true, Reference(引用)类型的值,它的base object是结果(1)而它的

property name是Identifier

4. 跳到第1步

5. 返回一个Reference类型,它的base object是null它的property name 是Identifier.

注:Reference(引用)类型的值是JS引擎使用的一种数据类型,它分为base object和property name两个部分。假设在JS代码中有obj.prop这样的表达式,那么解释成Reference类型,base object是对象obj,而property name是字符串”prop”

Scope Chain开始时被设为宿主对象,所以在全局代码中的变量就是宿主对象的属性。Scope Chain在执行时由JS引擎自动维护,编译型的引擎也会创建相应的运行时环境来做此事。Scope Chain一般在函数调用或者执行进入with块的时候改变。

函数的执行

JS函数执行并非简单地执行函数体(Function Body)中的JS代码,在此之前JS引擎会创建一个Activation Object,这个对象将会被作为Scope Chain的顶端,而函数的[[scope]]属性中的对象将被链接为其后续的对象。([[scope]]在函数定义时被确定,稍后的内容是关于[[scope]]如何定义的。)这意味着Function Body中的JS代码所使用的标识符都是按照上一部分所描述的,最先从Activation Object开始查找的。Activation Object创建时只有一个arguments属性,它不会继承Object.prototype的属性和方法。接下来的变量初始化(Variable Instantiation)将函数体中变量和函数声明的结果添加到Activation Object作为属性。

函数的[[scope]]属性

[[scope]]是ECMA262规定的对象的私有属性,理论上只有JS引擎可以访问,但FireFox的几个引擎(SpiderMonkey和Rhino)提供了私有属性__parent__来访问它(所以一会我们可以看一看它)。尽管所有对象都有[[Scope]]但是它只对函数对象有用。

对于函数声明和匿名函数表达式来说,[[scope]]就是它创建时的Scope Chain,但是对于有名字的函数表达式,[[scope]]顶端是一个新的JS对象(也就是继承了Object.prototype),这个对象被链到函数创建时的Scope Chain,它本身有一个属性就是函数的名字,这确保了函数内部的代码可以无误地访问自己的函数名进行递归。

举个例子

function f1()
{
return n>1?n*f1(n-1):1;
}

var f2=function f()
{
return n>1?n*f(n-1):1;
}



f1的递归是不安全的,而f2的递归是安全的。但是注意这仅仅是针对标准的规定而言,事实上IE并没有实现这个性质。
娱乐休闲专区A 影视预告B 音乐咖啡C 英语阶梯D 生活百科
网页编程专区E AMPZF HTMLG CSSH JSI ASPJ PHPK JSPL MySQLM AJAX
Linux技术区 N 系统管理O 服务器架设P 网络/硬件Q 编程序开发R 内核/嵌入
管理中心专区S 发布网址T 版主议事U 事务处理