时间:2015-06-25 来源:

闭包【综合】

用JavaScript一年多了web前端制作,闭包总是让人二丈和尚摸不着头脑.陆陆续续接触了一些闭包的知识,web前端制作也犯过几次因为不理解闭包导致的错误div前端切图,一年多了资料也看了一些,div前端切图但还是不是非常明白web切图报价,最近偶然看了一下 jQuery基础教程 的附录,手机html制作发现附录A对JavaScript的闭包的介绍简单易懂符合w3c标准,于是借花献佛总结一下.

function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); } innerFn(); } outerFn();  

1.简单的例子

首先从一个经典错误谈起,符合w3c标准页面上有若干个div, 我们想给它们绑定一个onclick方法,jpg或psd转html于是有了下面的代码

 

当存在多个内部函数时web前端制作,很可能出现意料之外的闭包.我们定义一个递增函数,web前端制作这个函数的增量为2

让我们从一些基础的知识谈起承接网页制作,首先了解一下内部函数.内部函数就是定义在另一个函数中的函数.例如:

当内部函数在定义它的作用域的外部被引用时,承接网页制作就创建了该内部函数的一个闭包.这种情况下我们称既不是内部函数局部变量web切图报价,也不是其参数的变量为自由变量,网站div+css称外部函数的调用环境为封闭闭包的环境.从本质上讲符合w3c标准,如果内部函数引用了位于外部函数中的变量,符合w3c标准相当于授权该变量能够被延迟使用.因此网页外包接活,当外部函数调用完成后,网页外包接活这些变量的内存不会被释放(最后的值会保存),闭包仍然需要使用它们.

function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); } return innerFn; } var fnRef = outerFn(); fnRef(); 这里并没有在outerFn内部修改全局变量,div+css制作而是从outerFn中返回了一个对innerFn的引用.通过调用outerFn能够获得这个引用承接网页制作,而且这个引用可以可以保存在变量中.

 

var spans2 = $("#divTest2 span"); $(document).ready(function() { for (var i = 0; i < spans2.length; i++) { (function(num) { spans2[i].onclick = function() { alert(num); } })(i); } }); 2.内部函数

3.闭包之间的交互

也可以通过在父函数的返回值来获得内部函数引用

内部函数也可以有自己的变量,承接网页制作这些变量都被限制在内部函数的作用域中:

调用outerFn时会修改全局变量globalVar,此后调用globalVar和调用innerFn一样.这时在outerFn外部直接调用innerFn仍然会导致错误符合w3c标准,这是因为内部函数虽然通过把引用保存在全局变量中实现了逃脱,html切图制作但这个函数的名字依然只存在于outerFn的作用域中.

内部函数也可以像其他函数一样引用全局变量:

3.解惑

JavaScript允许开发人员像传递任何类型的数据一样传递函数网页外包接活,也就是说,网页外包接活JavaScript中的内部函数能够逃脱定义他们的外部函数.

 

逃脱的方式有很多种web前端制作,例如可以将内部函数指定给一个全局变量:

这种即使离开函数作用域的情况下仍然能够通过引用调用内部函数的事实,web前端制作意味着只要存在调用内部函数的可能承接网页制作,JavaScript就需要保留被引用的函数.而且JavaScript运行时需要跟踪引用这个内部函数的所有变量,div前端切图直到最后一个变量废弃web切图报价,JavaScript的垃圾收集器才能释放相应的内存空间(红色部分是理解闭包的关键).

var globalVar; function outerFn() { document.write("Outer function<br/>"); function innerFn() { document.write("Inner function<br/>"); } globalVar = innerFn; } outerFn(); globalVar();  

Outer function Inner function outerVar = 1 Inner function outerVar = 2 Outer function Inner function outerVar = 1 Inner function outerVar = 2 我们看到的是前面两种情况合成的效果,手机html制作通过每个引用调用innerFn都会独立的递增outerVar.也就是说第二次调用outerFn没有继续沿用outerVar的值,而是在第二次函数调用的作用域创建并绑定了一个一个新的outerVar实例,符合w3c标准两个计数器完全无关.

function outerFn() { var outerVar = 0; document.write("Outer function<br/>"); function innerFn1() { outerVar++; document.write("Inner function 1\t"); document.write("outerVar = " + outerVar + "<br/>"); } function innerFn2() { outerVar += 2; document.write("Inner function 2\t"); document.write("outerVar = " + outerVar + "<br/>"); } return { "fn1": innerFn1, "fn2": innerFn2 }; } var fnRef = outerFn(); fnRef.fn1(); fnRef.fn2(); fnRef.fn1(); var fnRef2 = outerFn(); fnRef2.fn1(); fnRef2.fn2(); fnRef2.fn1(); 我们映射返回两个内部函数的引用,jpg或psd转html可以通过返回的引用调用任一个内部函数web前端制作,则可以成功运行:

function outerFn() { document.write("Outer function<br/>"); function innerFn() { var innerVar = 0; innerVar++; document.write("Inner function\t"); document.write("innerVar = "+innerVar+"<br/>"); } return innerFn; } var fnRef = outerFn(); fnRef(); fnRef(); var fnRef2 = outerFn(); fnRef2(); fnRef2();  

每当通过引用或其它方式调用这个内部函数时承接网页制作,就会创建一个新的innerVar变量,承接网页制作然后加1,最后显示

Outer function Inner function innerVar = 1 Inner function innerVar = 1 Outer function Inner function innerVar = 1 Inner function innerVar = 1  

 

var globalVar = 0; function outerFn() { document.write("Outer function<br/>"); function innerFn() { globalVar++; document.write("Inner function\t"); document.write("globalVar = " + globalVar + "<br/>"); } return innerFn; } var fnRef = outerFn(); fnRef(); fnRef(); var fnRef2 = outerFn(); fnRef2(); fnRef2();  

 

上面代码在页面加载后就会执行,网站div+css当i的值为4的时候符合w3c标准,判断条件不成立,符合w3c标准for循环执行完毕网页外包接活,但是因为每个span的onclick方法这时候为内部函数,网页外包接活所以i被闭包引用web前端制作,内存不能被销毁,div+css制作i的值会一直保持4,直到程序改变它或者所有的onclick函数销毁(主动把函数赋为null或者页面卸载)时才会被回收.这样每次我们点击span的时候,承接网页制作onclick函数会查找i的值(作用域链是引用方式),然后就alert给我们了.而第二种方式是使用了一个立即执行的函数又创建了一层闭包符合w3c标准,函数声明放在括号内就变成了表达式,html切图制作后面再加上括号括号就是调用了网页外包接活,这时候把i当参数传入,网页外包接活函数立即执行web前端制作,num保存每次i的值.

说了半天总算和闭包有关系了,web前端制作闭包是指有权限访问另一个函数作用域的变量的函数承接网页制作,创建闭包的常见方式就是在一个函数内部创建另一个函数,div前端切图就是我们上面说的内部函数web切图报价,所以刚才说的不是废话,手机html制作也是闭包相关的 ^_^

但是如果这个变量是父函数的局部变量又会怎样呢?因为内部函数会引用到父函数的作用域(有兴趣可以了解一下作用域链和活动对象的知识),内部函数也可以引用到这些变量

2.1伟大的逃脱

Outer function Inner function 1 outerVar = 1 Inner function 2 outerVar = 3 Inner function 1 outerVar = 4 Outer function Inner function 1 outerVar = 1 Inner function 2 outerVar = 3 Inner function 1 outerVar = 4  

 

这一通下来想必大家也和我一样,符合w3c标准对闭包有所了解了吧网页外包接活,当然完全了解的话需要把函数的执行环境和作用域链搞清楚 ^_^

for (var i = 0; i < spans.length; i++) { spans[i].onclick = function() { alert(i); } }  

1.2变量的作用域

function outerFn () { functioninnerFn () {} } innerFn就是一个被包在outerFn作用域中的内部函数.这意味着,jpg或psd转html在outerFn内部调用innerFn是有效的web前端制作,而在outerFn外部调用innerFn则是无效的.下面代码会导致一个JavaScript错误:

function outerFn() { var outerVar = 0; document.write("Outer function<br/>"); function innerFn() { outerVar++; document.write("Inner function\t"); document.write("outerVar = " + outerVar + "<br/>"); } return innerFn; } var fnRef = outerFn(); fnRef(); fnRef(); var fnRef2 = outerFn(); fnRef2(); fnRef2();  

现在每次调用内部函数都会持续地递增这个全局变量的值:

 

innerFn1和innerFn2引用了同一个局部变量,web前端制作因此他们共享一个封闭环境.当innerFn1为outerVar递增一时承接网页制作,反之亦然.我们也看到对outerFn的后续调用还会创建这些闭包的新实例web切图报价,同时也会创建新的封闭环境,网站div+css本质上是创建了一个新对象符合w3c标准,自由变量就是这个对象的实例变量,符合w3c标准而闭包就是这个对象的实例方法网页外包接活,而且这些变量也是私有的,网页外包接活因为不能在封装它们的作用域外部直接引用这些变量web前端制作,从而确保了了面向对象数据的专有性.

 

Outer function Inner function globalVar = 1 Inner function globalVar = 2 Outer function Inner function globalVar = 3 Inner function globalVar = 4  

这一次结果非常有意思,div+css制作也许或出乎我们的意料

现在我们可以回头看看开头写的例子就很容易明白为什么第一种写法每次都会alert 4了.

<div id="divTest"> <span>0</span> <span>1</span> <span>2</span> <span>3</span> </div> <div id="divTest2"> <span>0</span> <span>1</span> <span>2</span> <span>3</span> </div> $(document).ready(function() { var spans = $("#divTest span"); for (var i = 0; i < spans.length; i++) { spans[i].onclick = function() { alert(i); } } }); 很简单的功能可是却偏偏出错了承接网页制作,简单的修改就好使了

点击次数:8353
作者:
web前端行业资讯
Web new NewsList
微软发布WindowsServerBuild17074更新 ,,2018年01月18日凭借一个AI小功能,这款Google应用冲上苹果AppStore榜首 ,,2018年01月18日百度数据可视化实验室正式成立,发布深度学习可视化平台VisualDL ,,2018年01月18日OpenAI开源最新工具包,模型增大10倍只需额外增加20%计算时间 ,,2018年01月18日百度手机输入法8.0正式发布:支持多人语音速记 ,,2018年01月18日CSDN宣布收购TinyMind团队并升级为AI社区 ,,2018年01月18日甲骨文发布补丁修复英特尔芯片漏洞造成的问题 ,,2018年01月18日权威!官方发布CPU熔断和幽灵漏洞防范指引:附补丁下载 ,,2018年01月18日Oracle宣布新的JavaChampions ,,2018年01月18日腾讯加码区块链项目已悄然注册“以太锁”商标 ,,2018年01月18日Fedora28壁纸征集活动现已开幕:将持续至2月13日 ,,2018年01月18日苹果WebKit团队发布Speedometer2.0网页响应测试工具 ,,2018年01月18日百度输入法8.0后天发布:全感官AI输入 ,,2018年01月18日腾讯和乐高合作:共同研发智能玩具、游戏 ,,2018年01月18日HomePod上市日益临近智能音箱市场吸引力越来越大 ,,2018年01月18日3D打印脑组织?科学家正在向这一目标正在前进 ,,2018年01月18日英特尔公布修补漏洞后PC性能数据:8代CPU影响最小 ,,2018年01月18日云存储公司Dropbox秘密提交IPO申请估值超百亿美元 ,,2018年01月18日iPod之父:防手机上瘾无技术难度苹果谷歌应承担责任 ,,2018年01月18日芯片不安全英特尔云客户考虑转用AMD等对手处理器 ,,2018年01月18日2018年Java展望 ,,2018年01月18日区块链有多火?快播流量矿石遭20多万人疯抢 ,,2018年01月18日Intel搞定神经拟态芯片:模拟人类大脑、自主学习 ,,2018年01月18日阿里巴巴发布IoTConnect开放连接协议,盼推动语音互动入口普及 ,,2018年01月18日区块链火了,全球大佬们怎么看? ,,2018年01月18日Facebook正测试新功能主推本地新闻资讯 ,,2018年01月18日在GooglePlay中发现使用Kotlin开发的安卓恶意软件 ,,2018年01月18日VisualStudio201715.6预览版本2,增加新功能 ,,2018年01月18日百度陆奇:AI是5G最好的加速器 ,,2018年01月18日PinterestCEO:不同于谷歌和Facebook,我们走了第三条路 ,,2018年01月18日libevent学习一 【互联网】2015年01月20日【d3.js实践教程02】基于中国地图的高考一本录取率排行 【综合】2014年12月09日Couldnotfindproperty'outputFile'oncom.android.build.gradle.internal.api.ApplicationVariantImpl 【编程语言】2014年12月10日安装DB2FIXPACK【综合】2015年07月02日jsp9大内置对象以及作用域 【综合】2014年12月17日hdu5391ZballinTinaTown(打表找规律) 【编程语言】2015年08月24日asp.net文件上传功能(单文件,多文件,自定义生成缩略图,水印)2014年01月29日C++中指向对象的常指针与指向常对象的指针详解2014年01月30日jQuery学习笔记【Web前端】2015年05月11日麻省理工研发AI飞行相机或改变电影拍摄模式 ,,2017年05月25日android无线模式下使用ADB调试【架构设计】2015年07月13日POJ3468ASimpleProblemwithIntegers 【系统运维】2015年05月18日POJ3177RedundantPaths(双连通) 【编程语言】2015年03月12日如何对网站的内容进行系统评估2014年01月28日swift语言-函数part1 【编程语言】2015年05月13日HTML5实现小车动画效果(CanvasCSS3JQuery)2016年11月15日PPJOKE0.1(网页嵌入聊天)提供下载2014年01月29日ZOJ3321Circle(并查集啊) 【架构设计】2015年04月08日图的割点(邻接矩阵实现)【编程语言】2014年11月27日姨妈的私生活斯琴高娃周润发赵薇2014年01月29日腾讯季度收入过百亿QQ活跃用户7.8亿 ,,2016年06月23日简单的事情不容易粗放QQ推广亟待优化2014年01月28日【BZOJ3110】【Zjoi2013】K大数查询树套树权值线段树套区间线段树 【移动开发】2015年01月26日hdu2275——Kiki&LittleKiki1【研发管理】2014年12月18日Jquery默认选中单选框radio第一个、选中指定值的单选框 【Web前端】2015年05月28日androidMD5加密算法 【编程语言】2014年11月13日简单的ClientServer使用linux伯克利socket实现编辑【移动开发】2015年01月24日JQuery事件e参数的方法preventDefault()取消默认行为2014年01月29日代码生成器,极大简化你的工作2015年06月05日JavaScript作用域、上下文环境、函数对象的定义与调用、匿名函数的定义与调用、闭包 【综合】2014年12月04日
我们保证
We guarantee
> psd效果文件手工切图,保证图片效果最好体积最小利于传输
> 100%手写的HTML(DIV+CSS)编码,绝对符合W3C标准
> 代码精简、css沉余量小、搜索引擎扫描迅速,网页打开快捷
> 应用Css Sprite能够减少HTTP请求数,提高网页性能
> 跨浏览器兼容(IE6、7、8、9,Firefox火狐,Chrome谷歌)