探讨js闭包
背景:爱就要大胆说出来,对于编程我只想说,喜欢就大胆写出来。喜欢却不行动那就意味着失败。所以,对于在研究编程的猿们,我对同伴们说,大胆的学,大胆的写。呵呵,说这些其实无非是给我自己点动力,写下去的勇气。
今天写的是js闭包,这一个一直被我忽视的美。怎么说呢,其实之前我这人特别讨厌用闭包,为什么呢,因为习惯了写后台代码的人都知道,函数内部是不可以嵌套定义函数的。所以这一思想我之前一直没有转变,也感觉js的这样写法很“特别、很奇怪、甚至感觉没有必要,这也是我不想用的根本原因了。背景交代完毕。
额。。。好像还没有说啥是闭包了。算了,我表达能力不好,还是先从闭包的特点来解释吧,这样可能大家好理解点。
js闭包的特点:1:闭包外层是个函数。2:闭包内部都有函数。3:闭包会return内部函数。4:闭包返回的函数内部不能有return.(因为这样就真的结束了)。5:执行闭包后,闭包内部变量会存在,而闭包内部函数的内部变量不会存在。(说明:这些不是我写的,是从度娘上一位仁兄哪里拷过来的。不过我也是这么理解的。。。^_^)
简单吧、直观吧。但是这个很重要哦。大家仔细理解下。说了这么多,我还是以一个简单的例子来说明这几点吧。
function a() {
var i = 0;
function b() {
alert(++i);
}
return b;
}
var c = a();
c();//返回 1
c();//返回 2
看看上面这段简单的例子,这个例子也是我刚学习时候看到的,当然相信很多人如果了解过js闭包的人都有看过。例子和简单,但是用到的js闭包的思想哦。我们先来对照闭包的特点来逐一说明吧。特点一:闭包外层是个函数,这里说的就是a函数了; 特点二:闭包内部有函数,也就是b函数了。(其实这里可以直接返回function,也就是直接返回匿名函数,这里这样写也是为了大家好理解。);特点三:闭包返回b函数;特点四:b函数不能有return;特点五:这点很重要,涉及到js垃圾回收机制(GC)。这里说下js的垃圾回收机制。
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。(摘自园友:Leo_wlCnBlogs的一篇博文中的一句话。下面也有部分转与此。小弟在此感谢!^_^)
这样看是不是感觉闭包其实也很简单啊。所以一个理解就是:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
所谓“js闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中 的临时变量。这使得只要目标 对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目 标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新的值,和上次那次调用的是各自独立的。
js闭包的作用:简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的 执行需要依赖a中的变量。这是对闭包作用的非常直白的描述。闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。(从上面代码的运行中我们可以看出来)
使用js闭包的注意点:是不是大家看到既然闭包这么好用,那我们以后就常用闭包就好了啊,其实不然。为什么?因为从上面的js垃圾回收机制我们就可以看出,滥用闭包会导致内存消耗,导致网页加载慢等各种问题。所以,在不必要的情况下尽量少写闭包。
最后一点是对我们这些猿们的激励话吧,如果你想成为狮,请学好闭包。对了,闭包在开发插件的时候也是常用的。在接下来的jquery插件开发系列中我会着重提及到的。用园友大师的话说:理解js的闭包是迈向高级JS程序员的必经之路,理解了其解释和运行机制才能写出更为安全和优雅的代码。
如有想共同探讨、共同学习的同仁,随时联系我,QQ:296319075 ,注明园友就好,同时也希望大家也能提出宝贵意见,不吝赐教。秉承共同探讨、共同进步!如有转载,请注明出处,谢谢!^_^
探讨js闭包的更多相关文章
- 浅谈js闭包(closure)
相信很多从事js开发的朋友都或多或少了解一些有关js闭包(closure)的知识. 本篇文章是从小编个人角度,简单地介绍一下有关js闭包(closure)的相关知识.目的是帮助一些对js开发经验不是很 ...
- js闭包的作用域以及闭包案列的介绍:
转载▼ 标签: it js闭包的作用域以及闭包案列的介绍: 首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- Js闭包常见三种用法
Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...
- js闭包之初步理解( JavaScript closure)
闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解. 要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域, ...
- (原创)JS闭包看代码理解
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...
- js闭包理解
js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...
- js闭包理解实例小结
Js闭包 闭包前要了解的知识 1. 函数作用域 (1).Js语言特殊之处在于函数内部可以直接读取全局变量 <script type="text/javascript"> ...
- Js闭包的用途
本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...
随机推荐
- java实现sendemail
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</arti ...
- rabbitmq的vhost与用户管理
当我们在创建用户时,会指定用户能访问一个虚拟机,并且该用户只能访问该虚拟机下的队列和交换机,如果没有指定,默认的是”/”;一个rabbitmq服务器上可以运行多个vhost,以便于适用不同的业务需要, ...
- BZOJ2276:[POI2011]Temperature
浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...
- MySQL 数据库备份种类以及常用备份工具汇总
1,数据库备份种类 按照数据库大小备份,有四种类型,分别应用于不同场合,下面简要介绍一下: 1.1完全备份 这是大多数人常用的方式,它可以备份整个数据库,包含用户表.系统表.索引.视图和存储过程等所有 ...
- 根据VM的TAG开停机
公有云一个非常大的优势,就是可以根据需求进行开停机.由于计费是按时进行的,从而实现节省成本. Azure上用脚本按时开停机已经有很多部署的案例.本文将介绍采用VM Tag中规定的时间进行开停机的脚本. ...
- java事件练习!!
总结:不晓得怎么跟书上的运行结果显示的...希望标签竖直排列 package com.bc; import java.awt.Color; import java.awt.FlowLayout; im ...
- Lib之过?Java反序列化漏洞通用利用分析
转http://blog.chaitin.com/ 1 背景 2 Java反序列化漏洞简介 3 利用Apache Commons Collections实现远程代码执行 4 漏洞利用实例 4.1 利用 ...
- mjpg-streamer在Ubuntu下编译,运行
1.将USB摄像头插上,查看是否找到设备,输入: wp@ubuntu:/home/$ ls /dev/video* /dev/video0 2.安装必要的软件集: sudo apt-get ...
- Recovery of DISKGROUP in VXVM (ZT)
http://gurkulindia.com/main/2012/03/recovery-of-diskgroup-in-vxvm-veritas-volume-manager/# Since lon ...
- C#一般处理程序 ashx.cs使用Session报错问题
HttpContext.Current.Session["UserID"].ToString();//报错,报Session为Null, 此时需要添加引用和继承IRequiresS ...