理解Javascript_15_作用域分配与变量访问规则,再送个闭包


Posted in Javascript onOctober 20, 2010

作用域分配与变量访问规则

在 ECMAScript 中,函数也是对象。函数对象在变量实例化过程中会根据函数声明来创建,或者是在计算函数表达式或调用 Function 构造函数时创建。(关于'函数对象'请见《理解Javascript_08_函数对象》)。每个函数对象都有一个内部的 [[scope]] 属性,这个属性也由对象列表(链)组成。这个内部的[[scope]] 属性引用的就是创建它们的执行环境的作用域链,同时,当前执行环境的活动对象被添加到该对象列表的顶部。当我们在函数内部访问变量时,其实就是在作用域链上寻找变量的过程。

理论性太强了(总结死我了!),还是让我们来看一段代码吧:

<script type="text/javascript"> 
function outer(){ 
var i = 10; 
function inner(){ 
var j = 100; 
alert(j);//100 
alert(i);//10 
alert(adf); 
} 
inner(); 
} 
outer(); 
</script>

下图清晰的展现了上述代码的内存分配与作用域分配情况:
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
下面来解释一下:
1.载入代码,创建全局执行环境,此时会在可变对象(window)中添加outer变量,其指向于函数对象outer,此时作用域链中只有window对象.
2.执行代码,当程序执行到outer()时,会在全局对象中寻找outer变量,成功调用。
3.创建outer的执行环境,此时会新创建一个活动对象,添加变量i,设置值为10,添加变量inner,指向于函数对象inner.并将活动对象压入作用域链中.并将函数对象outer的[[scope]]属性指向活动对象outer。此时作用域链为outer的活动对象+window.
4.执行代码,为 i 成功赋值。当程序执行到inner()时,会在函数对象outer的[[scope]]中寻找inner变量。找到后成功调用。
5.创建inner的执行环境,新建一个活动对象,添加变量j,赋值为100,并将该活动对象压入作用域链中,并函数对象inner的[[scope]]属性指向活动对象inner.此时作用域链为:inner的活动对象+outer的活动对象+全局对象.
6.执行代码为j赋值,当访问i、j时成功在作用域中找到对应的值并输出,而当访问变量adf时,没有在作用域中寻找到,访问出错。

注:通过内存图,我们会发现作用域链与prototype链是如此的相象。这说明了很多问题...(仁者见仁智者见智,自己探寻答案吧!)

闭包原理
在我们了解了作用域的问题之后,对于闭包这个问题已经很简单了。什么是闭包?闭包就是封闭了外部函数作用域中变量的内部函数。
我们来看一个典型的闭包运用:生成increment值

<script type="text/javascript"> 
var increment = (function(){ 
var id = 0; 
return function(){ 
return ++id; 
} 
})() 
alert(increment());//1 
alert(increment());//2 
</script>

外层匿名函数返回的是一个内嵌函数,内嵌函数使用了外层匿名函数的局部变量id。照理外层匿名函数的局部变量在返回时就超出了作用域因此increment()调用无法使用才对。这就是闭包Closure,即函数调用返回了一个内嵌函数,而内嵌函数引用了外部函数的局部变量、参数等这些应当被关闭(Close)了的资源。这是怎么一回事呢?让我们来寻找答案:
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
根据Scope Chain的理解可以解释,返回的内嵌函数已经持有了构造它时的Scope Chain,虽然outer返回导致这些对象超出了作用域、生存期范围,但JavaScript使用自动垃圾回收来释放对象内存: 按照规则定期检查,对象没有任何引用才被释放。因此上面的代码能够正确运行。

参考:
http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html
http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html

Javascript 相关文章推荐
JS获取当前日期和时间的简单实例
Nov 19 Javascript
jquery动态加载select下拉框示例代码
Dec 10 Javascript
详谈JavaScript内存泄漏
Nov 14 Javascript
jquery制作多功能轮播图插件
Apr 02 Javascript
jQuery判断一个元素是否可见的方法
Jun 05 Javascript
jQuery图片旋转插件jQueryRotate.js用法实例(附demo下载)
Jan 21 Javascript
深入理解bootstrap框架之第二章整体架构
Oct 09 Javascript
基于JavaScript实现报警器提示音效果
Oct 27 Javascript
js推箱子小游戏步骤代码解析
Jan 10 Javascript
用Axios Element实现全局的请求loading的方法
Mar 15 Javascript
vue请求服务器数据后绑定不上的解决方法
Oct 30 Javascript
Vue的过滤器你真了解吗
Feb 24 Vue.js
理解Javascript_14_函数形式参数与arguments
Oct 20 #Javascript
理解Javascript_13_执行模型详解
Oct 20 #Javascript
用jquery与css打造个性化的单选框和复选框
Oct 20 #Javascript
Jquery插件之多图片异步上传
Oct 20 #Javascript
jquery判断checkbox(复选框)是否被选中的代码
Oct 20 #Javascript
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
Oct 20 #Javascript
JQuery 拾色器插件发布-jquery.icolor.js
Oct 20 #Javascript
You might like
浅析PHP中的字符串编码转换(自动识别原编码)
2013/07/02 PHP
在win7中搭建Linux+PHP 开发环境
2014/10/08 PHP
PHP往XML中添加节点的方法
2015/03/12 PHP
js获取单元格自定义属性值的代码(IE/Firefox)
2010/04/05 Javascript
IE中jquery.form中ajax提交没反应解决方法分享
2012/09/11 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
jQuery满意度星级评价插件特效代码分享
2015/08/19 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
利用原生JS自动生成文章标题树的实例
2016/08/22 Javascript
Javascript中判断一个值是否为undefined的方法详解
2016/09/28 Javascript
BootStrap框架中的data-[ ]自定义属性理解(推荐)
2017/02/14 Javascript
vue 项目常用加载器及配置详解
2018/01/22 Javascript
Vue-router的使用和出现空白页,路由对象属性详解
2018/09/03 Javascript
js实现查询商品案例
2020/07/22 Javascript
[09:59]DOTA2-DPC中国联赛2月7日Recap集锦
2021/03/11 DOTA
Python常用的文件及文件路径、目录操作方法汇总介绍
2015/05/21 Python
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
PyQt5实现无边框窗口的标题拖动和窗口缩放
2018/04/19 Python
Python3.5基础之变量、数据结构、条件和循环语句、break与continue语句实例详解
2019/04/26 Python
新手如何发布Python项目开源包过程详解
2019/07/11 Python
python如何编写类似nmap的扫描工具
2020/11/06 Python
VSCode中autopep8无法运行问题解决方案(提示Error: Command failed,usage)
2021/03/02 Python
使用html5+css3来实现slider切换效果告别javascript+css
2013/01/08 HTML / CSS
详解html5 canvas 微信海报分享(个人爬坑)
2018/01/12 HTML / CSS
曼联官方网上商店:Manchester United Direct
2017/07/28 全球购物
孕妇内衣和胸罩:Cake Maternity
2018/07/16 全球购物
简单说说tomcat的配置
2013/05/28 面试题
什么是GWT的Module
2013/01/20 面试题
药学专业大学生个人的自我评价
2013/11/04 职场文书
森林防火标语
2014/06/23 职场文书
门面房租房协议书
2014/08/20 职场文书
幼儿园教师的自我评价范文
2014/09/17 职场文书
领导班子奢靡之风查摆问题及整改措施
2014/09/27 职场文书
师德标兵先进事迹材料
2014/12/19 职场文书
2015年助理工程师工作总结
2015/04/03 职场文书
2015年食品安全工作总结
2015/05/15 职场文书