一个初学者对闭包的理解
2015-04-06 22:27
197 查看
不知道闭包算不算js的难点,反正我在闭包这一部分花了很多时间,不过幸运的是还是有很多收获的。我不知道我的理解是不是正确,不过把我自己的理解分享一下,如果那里有不对的地方,还希望大家可以告诉我,让我赶快改正呢~
《Javascript高级程序设计》上对闭包的定义是:有权限访问另一个函数作用域中的变量的函数。也就是说,闭包是一个函数,那什么样的函数才能是闭包呢?他能访问另一个函数作用域中的变量。这样的解释让我们直接想起了一个函数的内部函数,因为根据作用域链的规则,只有嵌套的函数才能达到这个效果。并且这个闭包函数是作为父函数的返回值返回,而且这个闭包函数通常是个匿名函数。
可能说这么多的书面语依旧很晦涩难懂,所以嘞,就举个例子来帮助理解。
PS:例子来源于《Javascript 高级程序设计》一书,但代码解释是根据我的理解,有什么不对的地方好iaxiwnagdajia可以指出来,谢谢~
首先 i 是 createFunction 的活动对象,但被一个匿名函数使用并作为返回值而形成闭包。因为匿名函数需要将i 返回,所以i同样被添加为匿名函数的活动对象,也就是 i<10 中的 i,和 return i 中的i 是同一个 i 而并非一般情况下的值传递。而 createFunction 返回时, i的值必然已经成为10了,前面已经说了i 是同一个i 那匿名函数内部的 i也是10 了。
再看一段常用解决方案的代码
上面这段代码添加了另一个有参的匿名函数。与上面代码相同的是无参的匿名函数因为返回了父函数的变量,所以把父函数的num活动对象添加为自己的活动对象,但有参匿名函数的num是由createFunction逐次引用而来的(因为值传递的缘故,createFunction返回之前的所有i++都被记录在了num里)。所以num值为从0到9 逐次i++而来的。
用这两个例子可以清楚的理解什么是闭包,用什么样的方式来解决闭包带给我的不想要的效果。再次总结一下,想要形成闭包,需要有一个函数访问了另一个函数作用域里的变量并添加为自己的活动对象。这样就导致变量不再是值传递而是就是同一个变量了。解决方式就是在添加一个可以值传递的匿名函数来取得值传递的结果。
我的理解就是介个样子的啦,正在做一些题目来验证我的理解是否正确,拜拜~
《Javascript高级程序设计》上对闭包的定义是:有权限访问另一个函数作用域中的变量的函数。也就是说,闭包是一个函数,那什么样的函数才能是闭包呢?他能访问另一个函数作用域中的变量。这样的解释让我们直接想起了一个函数的内部函数,因为根据作用域链的规则,只有嵌套的函数才能达到这个效果。并且这个闭包函数是作为父函数的返回值返回,而且这个闭包函数通常是个匿名函数。
可能说这么多的书面语依旧很晦涩难懂,所以嘞,就举个例子来帮助理解。
function createFunction(){ var result = new Array(); for(var i=0;i<10;i++){ result[i] = function(){ return i; }; } return result; }
PS:例子来源于《Javascript 高级程序设计》一书,但代码解释是根据我的理解,有什么不对的地方好iaxiwnagdajia可以指出来,谢谢~
首先 i 是 createFunction 的活动对象,但被一个匿名函数使用并作为返回值而形成闭包。因为匿名函数需要将i 返回,所以i同样被添加为匿名函数的活动对象,也就是 i<10 中的 i,和 return i 中的i 是同一个 i 而并非一般情况下的值传递。而 createFunction 返回时, i的值必然已经成为10了,前面已经说了i 是同一个i 那匿名函数内部的 i也是10 了。
再看一段常用解决方案的代码
function createFunction(){ var result = new Array(); for(var i=0;i<10;i++){ result[i] = function(num){ return function(){ return num; }; }(i); } return result; }
上面这段代码添加了另一个有参的匿名函数。与上面代码相同的是无参的匿名函数因为返回了父函数的变量,所以把父函数的num活动对象添加为自己的活动对象,但有参匿名函数的num是由createFunction逐次引用而来的(因为值传递的缘故,createFunction返回之前的所有i++都被记录在了num里)。所以num值为从0到9 逐次i++而来的。
用这两个例子可以清楚的理解什么是闭包,用什么样的方式来解决闭包带给我的不想要的效果。再次总结一下,想要形成闭包,需要有一个函数访问了另一个函数作用域里的变量并添加为自己的活动对象。这样就导致变量不再是值传递而是就是同一个变量了。解决方式就是在添加一个可以值传递的匿名函数来取得值传递的结果。
我的理解就是介个样子的啦,正在做一些题目来验证我的理解是否正确,拜拜~
相关文章推荐
- 循环一个节点列表(NodeList)或者数组,并且绑定事件处理函数引发对闭包的理解
- 一个初学者对于MVC架构的理解
- 一个简单的排序例子理解闭包作为参数
- 致java初学者:理解每一句java代码,给出一个简单实例。
- 一个初学者对于MVC架构的理解
- 一个初学者→全栈工程师的学习之路(1)——关于全栈工程师的理解
- 一个初学者对于MVC架构的理解
- 一个web前端初学者对html的简单理解
- java初学者求助关于java中一个意思的理解,百度有搜过,貌似是没找到,
- 深入理解闭包系列第四篇——常见的一个循环和闭包的错误详解
- 一个初学者对于MVC架构的理解
- 深入理解闭包系列第四篇——常见的一个循环和闭包的错误详解
- 一个初学者对于MVC架构的理解
- 一个初学者对于MVC架构的理解
- 一个初学者对于MVC架构的理解
- javascript执行上下文、作用域与闭包(第五篇)---一个例子的理解
- 一个初学者对事件和Observer模式的理解
- 深入理解JavaScript - 闭包 (四)常见的一个循环和闭包的错误详解
- [译文]Winsock API实现了一个Tcp服务器 - for 初学者
- J2EE初学者需要理解的问题