Javascript Closures (2)

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

上一篇文章中,简单介绍了下闭包(closure)和原型链,现在继续来研究闭包的内部机制。

对了,所有的东西都参考自这篇文章:Javascript Closures

执行环境(Execution Context)

执行环境(Execution Context) 是 ECMAScript 定义中的一个抽象概念,用来定义 ECMAScript 执行时所需要的一些行为。所有的 JS 代码都是在一个执行环境中被执行的,全局的代码是在一个全局的执行环境中执行的,而对函数的每次调用都会产生一个相应的执行环境。

当一个函数被调用的时候,就会进入到一个执行环境中,当另外一个函数被调用(或者同一个函数被递归调用)的时候就会进入到一个新的执行环境,而且当这个函数返回的时候,就会回到原来的执行环境中。所以,运行中的 JS 代码会有一个执行环境堆栈。

当一个执行环境被创建的时候,会发生一系列的事情。首先,它会创建一个 “Activation” 对象,不过这个对象很特别,因为它没有 prototype 并且不能在代码中直接引用。然后就会创建一个叫做 “arguments” 类似数组的对象,里面保存了传过来的参数,同时”Activation” 对象上会创建一个叫做 “arguments” 的属性并指向刚刚创建的 “arguments”对象。

接下来,执行环境就会被赋予一个作用域(scope)。一个作用域一般是由一系列的对象组成的,每个函数对象都有一个内部的 [[scope]] 属性,该属性也是由一系列的对象组成的。执行环境被赋予的那个 scope 就会被相应函数对象中的[[scope]] 属性所引用,同时会把开始创建的 “Activation” 对象插入到 scope 包含对象的最前面。

然后,就会使用ECMA 262提到的一个 “Variable” 对象进行变量初始化。事实上,前面创建的 “Activation” 对象和这里的”Variable” 对象其实是同一个对象。初始化的时候会在 “Variable” 对象上创建一些和函数定义中的参数同名的属性,如果有传过来的参数,就会把传过来的值赋给 “Variable” 对象上相应的属性(不然就赋值undefined)。如果有内部函数,那么就会创建一个函数对象,然后在 “Variable” 对象上创建一个和内部函数名字相同的属性,并把刚创建的函数对象赋值给它。变量初始化的最后一步就是在 “Variable” 对象上创建和函数内部的声明的本地变量同名的所有属性。

其实在变量初始化的时候,所有本地变量对应的 “Variable” 对象上的属性值都是 undefined,它们并没有被真正初始化。只有当执行到函数体内对它们赋值的语句的时候,它们才算是真正初始化了。

正是由于 “Activation” 对象和 “Variable” 对象其实是同一个对象,所以在代码中,”Activation” 对象上的 “arguments” 属性就可以像本地变量那样被引用。

最后,会对this关键字赋一个值。如果this被赋值为一个对象,那么以this.为前缀的所有属性都是指该对象上的属性,如果this 被赋值为 null ,那么它就指向 global 对象。

全局的执行环境相对于函数的执行环境来说,有那么一点不同。因为全局执行环境不需要参数,所以它也就不需要创建一个 “Activation” 对象来引用它们。全局执行环境也有一个 scope,不过它的 scope只包含一个对象,就是 global对象。它也会经过变量初始化,而且 global 对象会充当其中的 “Variable” 对象 ,这就是为什么在全局作用域声明的函数和变量都会作为 global 对象的属性。全局的执行环境中,this关键字指向的也是 global 对象。

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

猜你喜欢

  • JavaScript获取URL汇总

    2024-02-24 10:40:07
  • 如何把Oracle 数据库从 RAC 集群迁移到单机环境

    2024-01-28 06:29:05
  • asp中文件与文件夹常用处理函数(文件后缀、创建文件等)

    2011-02-20 11:00:00
  • 利用python做表格数据处理

    2021-07-15 10:39:08
  • javascript实现des解密加密全过程

    2023-07-02 05:18:50
  • Linux 修改Python命令的方法示例

    2023-10-04 18:16:58
  • MySQL 序列 AUTO_INCREMENT详解及实例代码

    2024-01-20 17:04:37
  • 基于matplotlib中ion()和ioff()的使用详解

    2021-11-23 17:54:27
  • Python warning警告出现的原因及忽略方法

    2021-10-16 10:59:02
  • MySQL如何实现两张表取差集

    2024-01-18 21:00:03
  • 用户体验设计答疑对话(半吊子和纯外行)

    2010-11-30 21:27:00
  • 解读Python脚本的常见参数获取和处理方式

    2022-07-17 03:36:02
  • JS关于 replace 取值、替换第几个匹配项问题小结

    2024-04-25 13:11:05
  • Python排序搜索基本算法之选择排序实例分析

    2023-10-05 20:01:12
  • php while循环控制的简单实例

    2024-05-11 10:03:54
  • 在应用环境中如何构造最优的数据库模式

    2009-04-01 14:28:00
  • python判断列表的连续数字范围并分块的方法

    2021-01-18 12:04:19
  • php5.4传引用时报错问题分析

    2023-11-14 15:03:17
  • Python利用随机函数生成变化图形详解

    2021-07-02 06:54:54
  • python实现同时给多个变量赋值的方法

    2021-10-09 07:02:50
  • asp之家 网络编程 m.aspxhome.com