前言
咳咳,叶大侠病了,昨天晚上回家时候在车上就不舒服,果然回来就挂了,本来还想今天接着上班撑下去的。但是昨天又看到一个IT巨子挂了,所以果断请了一个假!!!
但是早上7.00左右就迷迷糊糊的醒了,于是我在想我是不是该“身残志坚”一番。。。。
咳咳,以上玩笑,我们最近一起学习了很多CSS的东西,相信大家的CSS水平必定提高了吧???所以我们接下来一段时间来看看javascript吧,今天我们一起来看看闭包这个家伙!
本文参考:
http://www.cnblogs.com/TomXu/
http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html
http://www.cnblogs.com/frankfang/archive/2011/08/03/2125663.html
http://www.cnblogs.com/xiaotie/archive/2011/08/03/2126145.html
执行上下文(execution context)
又是上下文。。。无论是曾经学习.net时候的httpcontext,还是最近学习的block formatting context,都是上下文!
我们可以感觉到上下文的存在,就如感觉得到空气一样,我们却将它拿不出来,于是我们来看看执行上下文吧。
每次当控制器转到ecmascript可执行代码的时候,就会进入一个执行上下文。
活动的执行上下文组在逻辑上为一个堆栈,堆栈最底部一定是全局上下文(global context),顶部便是当前上下文
这个句话是很有玄机的哦,比如我们在一个函数环境中,我们首先用的是当前变量,若是没有就在父级函数中找,最后就在window中找。
PS:我们在写博客时候,中文没有问题,突然打一个字母上,你会发现整行都下移了1/2px,各位知道神马原因么???:)
eval在执行时候会产生一个调用上下文的东东(calling context),所以eval中定义的变量会影响函数环境中的变量。
作用域
闭包有作用域链有很多说不清道不明的关系,所以我们还是先看看作用域吧。
任何语言都会有作用域的概念,作用域便是变量与函数可访问范围,简称变量与函数的生命周期。
javascript中分为全局与局部两种,直白点window与function
复制代码
var name = '叶小钗';
function func() {
var id = '刀狂剑痴';
function alertId() {
alert(id);
}
alertId();
}
alert(name);//叶小钗
alert(id);//错误
func(); //刀狂剑痴
alertId();//错误
复制代码
此处name属于window属性便是全局的(有些浏览器自带name属性小心陷阱!)
func也是全局的,但是func这个作用域链包含了全局的,所以他可以访问外部的,但是外部不能访问进来。
链子。。。
在js中什么都是对象,函数和其它对象一样拥有很多属性,其中一个比较特殊的属性是:
[[scope]],scope翻译过来就是作用域,该属性包含了函数被创建的作用域中的对象的集合:
于是传说中的作用域链诞生了,他决定了哪些数据能被哪些函数访问。
当一个函数创建后,他的作用域链会被创建此函数的作用域中可访问的数据对象填充:
function add (a, b) {
var sum = a + b;
return sum;
}
在函数add创建时,他的作用域链中会填入一个全局对象,我们可以想象为window被压入了其[[scope]]
函数add的作用域在调用时会被用到,此时会创建一个“运行时上下文(execution context)”的内部对象,
他定义了函数执行时的环境,每个运行时上下文都有自己的作用域链,用于标识符解析,
当execution context创建时,而他的作用域链初始化为当前运行函数的[[scope]]所包含的对象。
所有相关的东东会按照其在函数中出现的顺序被复制到运行时上下文的作用域链中,他们共同组成了“活动对象(activation object)”,该对象就包含了函数的所有局部变量,参数,以及this,然后会排在我们作用域堆栈的顶端,我们可以最先获取,在运行时上下文结束(函数执行完毕)后,GC便会回收其空间。
在函数执行过程中,遇到一个变量便会经历一次标识符解析以决定从哪里获取以及存储数据。
这个过程首先从我们的“堆栈”顶端开始搜索,也就是活动对象的开始,若是有该变量便获取值,
若是没有则向下,知道window为止,没有就报错!
内存溢出
是想我们的浏览器内存若是搞满了,自然会浏览器崩溃,这是我们闭包之中需要考虑到的东西,因为他会导致我们一些东西无法GC。
闭包,神奇的魔法
闭包是神奇的魔法,因为他干了很多“坏事”,达到了出人意料的结果。
所谓闭包,便是function嵌套function,内部function可以访问外部的变量。
若是外部函数返回了内部函数,那么就闭了一个包
复制代码
1 function a() {
2     var name = '叶小钗';
3     function alertName() {
4         alert(name);
5     }
6     return alertName;
7 }
9 var func = a();
10 func();//叶小钗
复制代码
这个家伙是个坏孩子,怎么说呢,坏孩子招人疼啊!
我们看第9行,按我们之前的理解a执行结束后,整个活动对象是不是该被销毁?是不是与a有关的东西都该GC呢?
确实是这样的,但是我们这里就产生了一个闭包,阻止了其销毁,因为他里面的变量被用到了。
这里的一个事实便是外部的func访问到了a内部的变量!
一个经典的例子:
复制代码
1 function outer() {
2     var o = {};
3     for (var i = 0; i < 10; i++) {
4         o[i] = function () {
5             alert(i);
6         }
7     }
8     return o;
9 }
10 var funcs = outer();
11 for (var k in funcs) {
12     funcs[k]();
13 }
14 var s = '';
复制代码
我们来看这个,大家应该都比较熟悉了,我们知道他全部会打印10。
这是因为我们将outer给予funcs时候,outer的任务就完成啦,他现在内部的i便是10,我们现在再来调用函数,所有的i自然是指向一个[[scope]],所以变量i就是10!!!
要怎么解决大家也一目了然:
复制代码
1 function outer() {
2     var o = {};
3     for (var i = 0; i < 10; i++) {
4         o[i] = (function (i) {
5             alert(i);
6         })(i)
7     }
8     return o;
9 }
10 var funcs = outer();
11 for (var k in funcs) {
12     funcs[k]();
13 }
14 var s = '';
复制代码
相当于每次i是以一个副本的方式重新复制了一番,这个是可以达到我们的目的,但是有时候会对性能有一点影响,我们还是需要注意。
我们这里就不扯远了,在扯远的话我估计也露馅了。。。呵呵,最后我们来说一点应用吧。
闭包的应用
jquery时如何神奇的使用闭包的我现在还看不透,那是我1年后的任务,我这不关注他。
我这里说的应用时原来项目过程中遇到的,所以没有代码,我这边说下问题吧:
我们点击一个按钮,会向服务器发一个ajax请求,其中包含一些data,然后数据返回回来后我们又会用到开始传过去的一些data中的敏感信息,比如id。
这个时候一种比较笨的方法就是服务器给我们传回来,但是闭包出现后,我们便可以直接在函数中定义函数,而使用我们之前的data即可。
该例子有段时间了,大家看不清楚也没有关系啦。。。。
结语
叶大侠病了,求安慰,求按顶。。。。。
本文转自叶小钗博客园博客,原文链接:http://www.cnblogs.com/yexiaochai/archive/2013/06/15/3137288.html,如需转载请自行联系原作者

【初窥javascript奥秘之闭包】叶大侠病都好了,求不踩了:)相关推荐

  1. 【初窥javascript奥秘之事件机制】论“点透”与“鬼点击”

    前言 最近好好的研究了一番移动设备的点击响应速度,期间不断的被自己坑,最后搞得焦头烂额,就是现在可能还有一些问题,但是过程中感觉自己成长不少, 最后居然感觉对javascript事件机制有了更好的认识 ...

  2. 初窥Javascript单元测试,附带掌握一门新技能的学习方式。

    之前没感觉要学啥单元测试,项目中测试都是手动测的,但也没觉的啥,但最近看文章和招聘上也多多少少有这方面的需求,于是网上搜索了一下,只找到了一些文章,但介绍的都不是很详细或者说比较复杂,满满的伤,虽然看 ...

  3. Three.js初窥

    随着当今时期前端地愈来愈普及,页面实现的效果真的是越来越棒! 随着数字图像处理.人工智能技术的发展,展示给用户的视觉效果便不局限于平面的2D视觉效果,开始注重于全方位的3D立体展示效果,力求对于商品的 ...

  4. OBJECT_METHOD初窥

    一.  背景:Windows NT 的对象机制 Windows NT系统将各种资源以对象的方式进行组织和管理.虽然Windows NT内核使用C语言和汇编语言编写的,本身并未使用到C++中的面向对象机 ...

  5. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  6. 并发编程-01并发初窥

    文章目录 引言 思维导图 基础知识构建 涉及的知识点一览 高并发处理思路与手段一览 并发初窥 概念 并发问题模拟 代码 引言 说来惭愧,一直没有系统的梳理过并发编程的知识,这次借着学习_Jimin_老 ...

  7. 深入理解javascript原型和闭包(16)——完结

    之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就"不容易学".不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学java ...

  8. 深入理解javascript原型和闭包(17)——补this

    本文对<深入理解javascript原型和闭包(10)--this>一篇进行补充,原文链接:http://www.cnblogs.com/wangfupeng1988/p/3988422. ...

  9. 深入理解javascript原型和闭包(3)——prototype原型

    既typeof之后的另一位老朋友! prototype也是我们的老朋友,即使不了解的人,也应该都听过它的大名.如果它还是您的新朋友,我估计您也是javascript的新朋友. 在咱们的第一节(深入理解 ...

最新文章

  1. 一步一步学习Ultimus - 三、系统设置
  2. 软件获取手机的ime权限_【手机谷歌软件下载】【安卓+iOS】老湿机最爱~免翻,获取各种“特殊”资源!...
  3. Gridview 隐藏列
  4. Go 语言开发第一天,我的学习之路从这里开始
  5. [Leetcode][第718题][JAVA][最长重复子数组][动态规划][滑动窗口][暴力]
  6. link linux 跨设备,Linux中的两种link方式
  7. 移动互联网数据安全蓝皮报告(2021年)
  8. js 内置对象的方法
  9. 门当户对的感情真的很重要吗?
  10. iostat linux,iostat 命令详解
  11. linux dump 分析工具,使用 Crash 工具分析 Linux dump 文件
  12. 数控铣削图案及编程_数控铣削编程与操作设计有全套图纸.doc
  13. 从零开始写一个武侠冒险游戏-1-状态原型
  14. ERROR [BD 41-237]
  15. 概率论与数理统计大作业实验报告
  16. KingbaseES V8R6集群管理运维案例之---repmgr standby switchover故障
  17. 第二届『Citric杯』NOIP提高组模拟赛
  18. pytorch torchvision.ops.roi_align 示例
  19. 远程监控Swift生产服务器运行
  20. 工作之外如何实现自我提升

热门文章

  1. 4.4基于switch语句的译码器
  2. Qt 【遍历文件夹文件,为listwidgetItem设置图标】
  3. UNIX 网络编程知识,函数积累
  4. 深入理解JDBC的超时设置 转
  5. 5. 深入研究 UCenter API 之 MVC 网站下的用法(转载)
  6. Linux的追逐,Windows的穷途恼指日可待
  7. ASP网站实现防止被采集
  8. C#-invoke与sendmessage,findWindow的阻塞实验
  9. C# 编写Web API
  10. SQLiteOpenHelper使用详解