一个初学者对闭包的理解

不知道闭包算不算js的难点,反正我在闭包这一部分花了很多时间,不过幸运的是还是有很多收获的。我不知道我的理解是不是正确,不过把我自己的理解分享一下,如果那里有不对的地方,还希望大家可以告诉我,让我赶快改正呢~

《Javascript高级程序设计》上对闭包的定义是:有权限访问另一个函数作用域中的变量的函数。也就是说,闭包是一个函数,那什么样的函数才能是闭包呢?他能访问另一个函数作用域中的变量。这样的解释让我们直接想起了一个函数的内部函数,因为根据作用域链的规则,只有嵌套的函数才能达到这个效果。并且这个闭包函数是作为父函数的返回值返回,而且这个闭包函数通常是个匿名函数。

可能说这么多的书面语依旧很晦涩难懂,所以嘞,就举个例子来帮助理解。

1 function createFunction(){
2     var result = new Array();
3     for(var i=0;i<10;i++){
4         result[i] = function(){
5             return i;
6         };
7     }
8     return result;
9 }

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++而来的。

用这两个例子可以清楚的理解什么是闭包,用什么样的方式来解决闭包带给我的不想要的效果。再次总结一下,想要形成闭包,需要有一个函数访问了另一个函数作用域里的变量并添加为自己的活动对象。这样就导致变量不再是值传递而是就是同一个变量了。解决方式就是在添加一个可以值传递的匿名函数来取得值传递的结果。

我的理解就是介个样子的啦,正在做一些题目来验证我的理解是否正确,拜拜~

时间: 2024-08-28 01:50:15

一个初学者对闭包的理解的相关文章

作为一个初学者如何简单地理解闭包

闭包最直接的定义:函数可以记住并访问所在的词法作用域时,就产生了闭包,即使这个函数是在当前词法作用域之外执行的. 如下代码: function foo() { var a = 1; function bar() { console.log(a); } bar(); } foo(); // 1 kyle给的一个定义,首先给人的第一感觉就是,这不就是在说作用域的查找规则吗?因为就算一个初学者不懂闭包,依然能理解这种结果,原因很简单,因为bar函数是嵌套在foo函数中.确切来说,这并不算是闭包.这种作

深入理解闭包系列第四篇——常见的一个循环和闭包的错误详解

前面的话 关于常见的一个循环和闭包的错误,很多资料对此都有文字解释,但还是难以理解.本文将以执行环境图示的方式来对此进行更直观的解释,以及对此类需求进行推衍,得到更合适的解决办法 犯错 function foo(){ var arr = []; for(var i = 0; i < 2; i++){ arr[i] = function(){ return i; } } return arr; } var bar = foo(); console.log(bar[0]());//2 以上代码的运行

闭包的理解学习

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于Javascript初学者应该是很有用的. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外

javascript闭包的理解

闭包,是javascript中独有的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述. 1 初探 在接触一个新技术的时候,我首先会做的一件事就是:找它的demo code.对于码农们来说,代码有时候比自然语言更能理解一个事物. 其实,闭包无处不在,比如:jQuery.zepto的主要代码都包含在一个大的闭包中,所以下面我先写一个最简单最原始的闭包demo,好让你在大脑里 产生闭包的画面

javascript中重要概念-闭包-深入理解

在上次的分享中javascript--函数参数与闭包--详解,对闭包的解释不够深入.本人经过一段时间的学习,对闭包的概念又有了新的理解.于是便把学习的过程整理成文章,一是为了加深自己闭包的理解,二是给读者提供学习的途径,避免走弯路. 在javascript--函数参数与闭包--详解这篇文章中,我详细介绍了闭包的概念.以下的分享对闭包的基本概念只会稍稍带过.如果对闭包的概念不熟悉的同学,请移步至javascript--函数参数与闭包--详解. 以下的分享会分为如下内容: 1.let命令 2.闭包特

关于闭包的理解

发表一下关于闭包的理解:首先把每一个函数看成一个一个的"小黑屋"小黑屋里面可以看到外面的东西,但外面却看不到小黑屋里面的东西,就好比是函数可以访问外面全局变量,但是外面却访问不了"小黑屋"里面的变量:变量分为全局变量和局部变量:列:函数可以访问外面全局变量 var a=1; function fun1(){ alert(a); }fun1(); // 1 列:外面却访问不了"小黑屋"里面的变量 function fun2(){ var a=2;

javascript 闭包的理解

看过很多谈如何理解闭包的方法,但大多数文章,都是照抄或者解释<Javascript高级程序设计(第三版)>对于闭包的讲解,甚至例程都不约而同的引用高程三181页‘闭包与变量’一节的那个“返回数组各个项,结果各个项的值都相同”的例程,还有些文章的讲解过程上一步与下一步之间的跨度简直就是一步登天,让人反复看半天都无法理解. 闭包的理解需要很多概念做铺垫,包括变量作用域链.执行环境.变量活动对象.引用式垃圾内存收集机制等,如果对本文涉及的这些概念不理解,可以去找本<Javascript高级程序

作用域+闭包+this理解

函数预解析过程   函数会覆盖同名变量 也就是var  他的优先级高   如果是同名函数则后者覆盖前者   逐行解读代码的时候 表达式 和参数 会改变预解析仓库里面的值..也就是表达式能干掉函数   域和域之间的关系 <script>标签存在上下文关系   走完上下文标签的变量  下面的可以用上面的   自上而下  函数  json等 子级作用域到父级作用域的过程 叫作用域链        由里到外 当子级找不到变量 会到父级找  如果有表达式的话就会更改全局变量 也就是函数里面没有var  

javascript闭包的理解和实例

所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量. 顺便提示一下: 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域. with和eval除外,所以只能说JS的作用域机制非常接近词法作用域(Lexical scope). 下面是一个简单的使用全局变量的闭包实例: 1 var sWord="Hello,Welcome to web前端开发工程师的博客,请多多指教.&