Javascript Closures (2)(2)

作者:Dreamer 来源:Dreamer’s Blog 时间:2009-03-18 12:22:00 

scope 链 和 [[scope]] 属性

要了解 scope 链,首先需要了解的就是内部的 [[scope]] 属性。在ECMAScript 中,所有的函数都是对象,在执行函数声明或者表达式的时候会创建函数对象,它们也可以通过构造函数 Function 被创建。

在通过构造函数Function 来创建函数对象的时候,这个函数对象内部的 [[scope]] 属性总是指向一个只包含了global对象的scope链。通过声明或者表达式创建的函数对象内部的[[scope]]属性则指向其所在的执行环境的scope 链。

比如下面两段代码:


function exampleFunction(formalParameter)
{ ... // function body code 
}


var exampleFuncRef = function(){ 
... // function body code 
}

虽然写法有点不同,函数对象创建的时间也不同,但是由于它们所处的都是全局的执行环境,所以它们内部的[[scope]] 属性指向的scope 链只包含一个 global 对象。

内部函数有一些不同,因为它们是在函数内部定义的,所以执行环境就不是全局执行环境,scope链上的对象就比较多。看一下下面的代码:

function exampleOuterFunction(formalParameter){ 
    function exampleInnerFuncitonDec(){ 
        ... // inner function body 
    } 
... // the rest of the outer function body. 

 
exampleOuterFunction( 5 );

对于内部函数exampleInnerFuncitonDec()来说,当外部函数被调用的时候,就创建了一个新的执行环境和相应的Activation/Variable 对象,所以它内部的[[scope]]属性就指向了当前的scope链:包含了当前执行环境的Activation 对象以及外部函数的 [[scope]] 上的global对象。

由此我们看到,代码的逻辑和结构会自动控制 scope 链的创建。不过ECMAScript提供了一个 with 语句,使用它可以更改scope 链。

函数声明不会受到 with 语句的影响,因为它们在变量初始化的时候就已经创建相应的函数对象了,但是函数表达式可以,看下面的代码:


var y = {x:5};
function exampleFuncWith(){ 
var z; 
   with(y){ 
      z = function(){ 
          ... // inner function expression body; 
      } 
    } 
... 
}

由于使用了 with 语句,在函数执行的时候,内部函数 z 的 [[scope]] 属性指向的 scope 链的前面又会插入一个 y 对象,变成: y对象->当前执行环境的Activation对象->global对象。

接下来看一下标识符定位的问题。当代码运行的时候如果发现了某个标识符,就会在scope链中的对象上寻找与它对应的变量,从第一个开始依次找,如果找到就返回,不然就一直找到 scope 链的末尾。由于函数被调用的时候会创建新的执行环境,就会把相应的Activation/Variable 对象插入到 scope 链的前面,所以对于函数体中的标识符,总是会先检查是否有相对应的内部函数、参数或者本地变量。

标签:JavaScript,原型链,闭包,scope,closure
0
投稿

猜你喜欢

  • asp如何处理超时事件?

    2009-11-14 20:41:00
  • 如何从SQL数据库中调用图片?

    2009-11-15 19:59:00
  • SQL Server与Oracle、DB2的优劣对比

    2009-01-07 14:16:00
  • 如何利用数据库内容建立一个下拉式列表?

    2010-01-01 15:46:00
  • SQL SQL Server 2008中的新日期数据类型

    2009-03-10 15:01:00
  • Javascript 中对中文长度对行判断

    2009-07-05 18:39:00
  • asp如何准确获知对方来访问的时间和URL?

    2010-07-07 12:25:00
  • 将滚动条(scrollbar)保持在最底部的方法

    2008-02-21 10:05:00
  • asp怎么实现中文字符串按声母检索

    2010-05-16 21:19:00
  • 准备SQL Server 2008透明数据加密

    2009-01-22 14:18:00
  • 一个asp简单购物车教程

    2007-09-17 11:02:00
  • asp检测服务器XmlHttp组件支持情况

    2008-03-03 12:30:00
  • WAP2.0网页设计中的交互细节

    2010-08-12 20:50:00
  • PL/SQL编程经验小结开发者网络Oracle

    2010-07-18 13:27:00
  • 最令人蛋疼的10种用户体验设计师

    2011-08-05 18:51:07
  • 太有才了!让人称绝的404错误页面

    2007-08-19 15:51:00
  • 向上不间断(无缝)滚动图片js代码

    2007-09-24 20:22:00
  • 常用正则表达式例子及评注说明

    2008-01-03 13:04:00
  • asp如何选择访问速度最快的站点?

    2010-06-10 18:34:00
  • WIN2003无法上传较大的文件Request对象错误解决方法

    2007-08-10 09:44:00
  • asp之家 网络编程 m.aspxhome.com