经常被问到什么是闭包?

说实话闭包这个概念很难解释。JavaScript权威指南里有这么一段话:“JavaScript函数是将要执行的代码以及执行这些代码作用域构成的一个综合体。在计算机学术语里,这种代码和作用域额综合体叫做闭包。”。言外之意所有的JavaScript函数都是闭包。

有人会说,这个解释不对。我们经常说的闭包应该像下面的一串代码:

    var f1 = function(){
var a=1;
return function f2(){
a++;
alert(a)
}
}
var b = f1();
b(); //
b(); //

是的,这是闭包中的一个经典例子,也是我们通常说的闭包。在这段代码中,b便是闭包f2的函数。

为什么使用闭包?

写到这里,我们不得不先理解下JavaScript的特殊变量作用域和JavaScript的垃圾回收机制了。

(1)、什么是变量作用域呢?一个变量的作用域是程序中第一这个变量的区域。JavaScript的变量分为“全局变量”和“局部变量”。

全局变量:全局变量的作用域是全局性的,即在JavaScript代码中,它处处都有定义。我经常写一个“a=1”,这个变量“a”就被定义成了全局性的了。

局部变量:在函数之内声明的变量,就只在函数体内部定义,它的作用域是局部性的。函数的参数也是局部变量,它们只在函数体内有定义。在函数体内,局部变量的优先级比同名的全局变量要高,例如:

var a =1;
function f1(){
var a=2;
alert(a);
}
f1(); //

那么如果我把 变量“a”变成局部变量的话,例如:

function f1(){
var a=2;
}
alert(a);

就会报如下图的错误:

有人会说,怎么 可能会有这么奇葩的需求,下面我举个例子,大家就会发现,其实我们还是用过的。

闭包实例:

当我“点击”按钮时,效果如下:

代码我们也许会这么处理:

$('.button').click(function(){
var length = $('.list').find('li').length;
var timer =null;
for(var i=0;i<length;i++){
timer=setTimeout(function(){
if(i>length){
clearInterval(timer);
}
$('.list li').eq(i).css({'-webkit-transform':'scale('+(i+1)+')','marginLeft':(i+1)*50 +'px'})
console.log(i)
},i*2000)
}
})

运行之后你会发现,并没有出现我们想要的效果,打印“i”,发现,,怎么会输出了3次“3”呢,其实是for()里面的变量i的作用域问题,i的作用域仅在for循环的函数体内,怎么才能实现这个效果呢,我们可以做个小的改动,代码如下:

$('.button').click(function(){
var length = $('.list').find('li').length;
var timer =null;
for(var i=0;i<length;i++){
timer=setTimeout((function(i){
if(i>length){
clearInterval(timer);
}
$('.list li').eq(i).css({'-webkit-transform':'scale('+(i+1)+')','marginLeft':(i+1)*50 +'px'})
//console.log(i)
})(i),i*2000)
}
})

把“i”,当做参数传进去,这便构成了闭包。

(2)、什么是JavaScript的垃圾回收机制呢?

答:JavaScript不要求手动的释放内存,它使用一种称为垃圾收集的方法,JavaScript的解释器可以检测到何时程序不再使用一个对象了。当它确定了,一个对象是无用的时候,JavaScript的解释器就把该对象所占用的内存释放掉了。

所以综上所述,就不难理解,在f1函数里定义一个局部变量a,在f1函数外面,变量a会找不到,因为,它被释放掉了。

我们是不是可以这么认为“闭包的作用(或者定义)就是使私有的变量(也可以理解为局部变量)能够被多个函数共享,而不被JavaScript的解析器自动的从内存中释放掉

闭包的缺点:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

楼楼不才,对闭包的理解目前就这么多,等深入学习了,会再补充和修正的。推荐大家可以看看“阮一峰”老师写的“学习Javascript闭包(Closure)”,链接:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

JavaScript ---- 闭包(什么是闭包,为什么使用闭包,闭包的作用)的更多相关文章

  1. 《JavaScript 闯关记》之作用域和闭包

    作用域和闭包是 JavaScript 最重要的概念之一,想要进一步学习 JavaScript,就必须理解 JavaScript 作用域和闭包的工作原理. 作用域 任何程序设计语言都有作用域的概念,简单 ...

  2. [转]JavaScript中的匿名函数及函数的闭包

    JavaScript中的匿名函数及函数的闭包  原文地址:http://www.cnblogs.com/wl0000-03/p/6050108.html 1.匿名函数 函数是JavaScript中最灵 ...

  3. JavaScript中的匿名函数及函数的闭包(转)

    JavaScript中的匿名函数及函数的闭包  https://www.cnblogs.com/wl0000-03/p/6050108.html 1.匿名函数 函数是JavaScript中最灵活的一种 ...

  4. javascript进阶教程第三章--匿名和闭包--案例实战

    javascript进阶教程第三章--匿名和闭包--案例实战 一.学习任务 通过几个小练习回顾学过的知识点 二.实例 练习1: 实例描述:打开页面后规定时间内弹出一个新窗口,新窗口指定时间后自动关闭. ...

  5. 《你必须知道的javascript(上)》- 1.作用域和闭包

    1 作用域是什么 1.1 编译原理 分词/词法分析(Tokenizing/Lexing) 将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元(token). 解析/语 ...

  6. [Effective JavaScript 笔记] 第11条:熟练掌握闭包

    理解闭包三个基本的事实 第一个事实:js允许你引用在当前函数以外定义的变量. function makeSandwich(){ var magicIngredient=”peanut butter”; ...

  7. JavaScript中的匿名函数及函数的闭包

    1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没有函数名的函数. 1.1 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式 第一种: ...

  8. 读书时间《JavaScript高级程序设计》三:函数,闭包,作用域

    上一次看了第6章,面向对象.这里接着看第7章. 第7章:函数表达式 定义函数有两种方式:函数声明.函数表达式 //函数声明 function functionName(arg0,arg1,arg2){ ...

  9. JavaScript夯实基础系列(二):闭包

      在JavaScript中函数是一等公民.所谓一等公民是指函数跟其他对象一样,很普通,可以进行把函数存在数组中.作为参数传递.赋值给变量等操作.当函数作为另一个函数的返回值在外部调用时,跟该函数在函 ...

  10. 【转】JavaScript中的匿名函数及函数的闭包

    对闭包理解一直不甚明了,在此特转摘博文一篇以备查用. 原文地址:http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html 相关文章: ...

随机推荐

  1. android studio 设计任务内容和识别内容界面 (android stuido design task layout)

    本人android studio版本是 3.4.1,设计了一个任务内容和识别内容的界面,欢迎大家品尝. 界面显示如下图所示: 实现代码如下: <?xml version="1.0&qu ...

  2. git——修改已经提交并push后的commit注释

    把代码push到远程后,发现commit的注释居然多了几个错别字,不行,必须改了! 搜索了一些答案之后自己做了一个总结如下: ①修改倒数第次的commit 指令:$ git rebase -i HEA ...

  3. 阿里云高磊:API网关加速能力聚合与生态集成

    导读:本文中,阿里云高级技术专家高磊(花名:埃兰)将聚焦API网关加速能力聚合与生态集成,讲述API如何实现系统间的衔接和API网关的产品升级进程,重点展示了一些新功能.新体验和新变化. 大家下午好, ...

  4. J2EE学习篇之--Struts2技术详解

    前面说到了Struts1的相关知识,下面来说一下Struts2的相关知识,我们知道现在Struts2使用的比Struts1多,Struts2已经替代Struts1成为主流的框架了... 摘要 Stru ...

  5. Android中.9图片的了解和制作过程

    个部分(九宫格),分别为4个角,4条边,以及一个中间区域,4个角是不做拉升的,所以还能一直保持圆角的清晰状态,而2条水平边和垂直边分别只做水平和垂直拉伸,所以不会出现边会被拉粗的情况,只有中间用黑线指 ...

  6. 排序+并查集——cf1213F

    /* 有向边(pi,pi+1),形成链后进行dfs,求出dfs序 一个联通块内的元素必须是同一个字符,如果最后的联通块个数<k,说明不行 */ #include<bits/stdc++.h ...

  7. XSS的原理分析与解剖:第四章(编码与绕过)*******************未看**********************

    0×01前言 很抱歉,这第四章被我推了几个月,今天是元旦难得有空,就把第四章写下.我先把主要使用的编码说下,介绍完会说下绕过. 本文建议与<杂谈如何绕过WAF>一同阅读. 0×02 URL ...

  8. 在ag-grid表格上实现类似Excel中的按下enter键自动跳转到下一行对应的输入框功能,Angular4开发

    最近的项目使用ag-grid在Angular中处理表格,收到个需求是要能够同时修改大量的数据,按下Enter键的时候,光标得自动跳到下一行的对应列上. 方法一:用ag-grid自带的 enterMov ...

  9. (转)OpenFire源码学习之十七:HTTP Service插件

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43457645 HTTP Service插件 这里的http接口插件是神马? Openfi ...

  10. “今日头条杯”首届湖北省大学程序设计竞赛(网络同步赛 )--E. DoveCCL and Resistance

    题目描述:链接点此 这套题的github地址(里面包含了数据,题解,现场排名):点此 链接:https://www.nowcoder.com/acm/contest/104/D来源:牛客网 题目描述 ...