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 链的前面,所以对于函数体中的标识符,总是会先检查是否有相对应的内部函数、参数或者本地变量。


猜你喜欢
如何用Python将图片转为字符画

appium+python adb常用命令分享

python文件选择对话框的操作方法

一个css与js结合的下拉菜单支持主流浏览器

合理的网页设计具有哪些特征

教你使用Python连接oracle

浅析PEP572: 海象运算符
GO语言求100以内的素数
详解NodeJS框架express的路径映射(路由)功能及控制
python使用pandas进行量化回测

教会你完全搞定MySQL数据库 轻松八句话
详解javascript遍历方式
Golang接口型函数使用小结
ajax+asp无限级分类树型结构
python生成每日报表数据(Excel)并邮件发送的实例
pycharm使用anaconda全过程

Pytorch 定义MyDatasets实现多通道分别输入不同数据方式
Python删除列表中重复元素的七种方法举例
如何通过PHP实现Des加密算法代码实例
jupyter notebook 重装教程
