关于JS闭包
今天在敲代码的时候,发现很多JQ插件在写闭包的时候都会用到下面的写法:
(function ($) {
  ...
})(jQuery);
一时的好奇心驱使,我研究起了这一写法来。大家都知道,在 $ 没有被其他定义覆盖的情况下,$ 和 jQuery 是等价的,前者只是后者的缩写而已。
那为什么闭包的写法里fuction的形参是 $ 后面括号里却是 jQuery 呢?改写成 $ 会怎样?
后面括号里的 jQuery 实际上又是啥?
带着这两个疑问,在网上搜了一番,透过各种资料文档,总算是对闭包这东东有了一定的了解。
看了 http://www.cnblogs.com/jianghua/archive/2012/05/10/2493842.html 这篇文章后,我知道了这一写法的由来。
第一步:最初最常见形态,函数的定义 + 调用
function myFun($) {
    ...
}
myFun(jQuery);
第二步:匿名函数写法
var myFun = function($) {
    ...
}
myFun(jQuery);
第三步:给myFun调用加个括号(这一步很关键,相信看到这里,大家心中已然明了)
var myFun = function($) {
    ...
}
(myFun)(jQuery);
第四步:myFun的定义也省了,就变成
(function ($) {
  ...
})(jQuery);
这样一来,上面的2个问题一下子就解开了。
首先,JQ闭包的写法,function后面括号里的 $ 是形参没争议,后面那个括号里的 jQuery 其实是function调用时传进去的一个实参。
JQ闭包这样的写法,其实是把函数的【定义 + 调用】整合起来了。
既然 jQuery 是实参,而在 $ 没被其他定义覆盖的前提下,两者又是等价的。此时,将 jQuery 写成 $ 是完全没有问题的。
也就是:
(function ($) {
  ...
})($);
下面再看看我在百度文库里找到的资料
先看下面这个例子的代码:
function a(){
    var i=0;
    function b(){
        alert(++i);
    }
    return b;
}
var c = a();
c();         
这段代码有两个特点:
1、函数 b 嵌套在函数 a 内部;
2、函数 a 返回函数 b。
在执行完 var c=a() 后,变量 c 实际上是指向了函数 b,再执行 c() 后就会弹出一个窗口显示 i 的值(第一次为1)。
这段代码其实就创建了一个闭包,为什么?
因为函数 a 外的变量 c 引用了函数 a 内的函数 b。
就是说:当函数 a 的内部函数 b 被函数 a 外的一个变量引用的时候,就创建了一个闭包。
那如果 c 执行第二次呢,第三次呢?它的值又分别会是啥?
结果是执行第二次显示2,第三次显示3...
在 a 执行完并返回后,闭包作用使得 Javascript 的垃圾回收机制GC不会收回 a 所占用的资源,因为 a 的内部函数 b 的执行需要依赖 a 中的变量。
由于闭包的存在使得函数 a 返回后,a 中的 i 始终存在,这样每次执行 c(),i 都是自加1后 alert 出 i 的值。
闭包的应用场景
1、保护函数内的变量安全。如上面例子,函数 a 中 i 只有函数 b 才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
2、在内存中维持一个变量。如上面例子,由于闭包,函数 a 中 i 的一直存在于内存中,因此每次执行 c(),都会给i自加1。 以上两点是闭包最基本的应用场景,很多经典案例都源于此。
Javascript的垃圾回收机制
在 Javascript 中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
上面的例子中,因为函数 a 被 b 引用,b 又被 a 外的 c 引用,这就是为什么函数 a 执行后不会被回收的原因。
关于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 我们来看看闭包的用途. ... 
- js闭包和ie内存泄露原理
		也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ... 
- js闭包(closure),个人理解
		一.闭包概念理解 各种专业文献上对js"闭包"(closure)定义非常抽象,贼难看懂.我的理解是,闭包就是能够读取某函数内部变量的函数.由于在Javascript语言中只有在函数 ... 
随机推荐
- ibatis源码学习4_参数和结果的映射原理
			问题在详细介绍ibatis参数和结果映射原理之前,让我们先来思考几个问题.1. 为什么需要参数和结果的映射?相对于全自动的orm,ibatis一个重要目标是,通过维护POJO与SQL之间的映射关系,让 ... 
- 记一次艰苦卓绝的Discuz x3 论坛升级过程
			首先吐槽一下discuz 的官方论坛. 你要想下载到正确版本的discuz实在不容易找到. 有兴趣自己去看吧. 就是因为这个原因, 我本来想要安装x2.5版本(那时x3 还是Beta版本), 结果不小 ... 
- Wait--常见的等待类型
			--==================================================================================--SLEEP_BPOOL_FL ... 
- zTree动态加载
			@{ Layout = null;} <!DOCTYPE html> <html><head> <meta name="viewport" ... 
- performance checklist
			- embree integration 0w - uncompressed bvh nodes ... 
- 【04】循序渐进学 docker:Dockerfile
			写在前面的话 从前面我们简单的了解了镜像,也运行了容器,各种官方的镜像显然无法满足我们自己的需求,我们目的终究是运行自己的业务. 所以,本章节的 Dockerfile 就主要讲怎么在官方镜像的基础上制 ... 
- 如何使用OpenGL中的扩展
			如果你在Windows平台下开发OpenGL程序,那么系统中自带的OpenGL库就是1.1的,如果想使用1.2或者更高版本的OpenGL库,那么只能使用OpenGL扩展,在网上关于如何使用OpenGL ... 
- iOS开发其他相关
			1.iOS开发行情 1.1 iOS系统各个版本的占比查询 2.Xcode的使用 开发软件下载 Xcode Help(官方) 2.1 Xcode面板 Xcode面板 2.2 Xcode版本新功能 Xco ... 
- [ActionScript 3.0]  如何获得实例对象的类名及类
			package { import flash.display.DisplayObject; import flash.display.MovieClip; import flash.display.S ... 
- [转] 翻译130+VIM基本命令
			基础 :e filename 在编辑器中打开一个文件 :w 保存文件 :q 退出vim :q! 退出但不保存 :x 写文件(如果有做修改)并退出 :sav filename 保存为 . 在正常模式中重 ... 
