今天在敲代码的时候,发现很多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闭包的更多相关文章

  1. js闭包的作用域以及闭包案列的介绍:

    转载▼ 标签: it   js闭包的作用域以及闭包案列的介绍:   首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...

  2. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  3. Js闭包常见三种用法

        Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...

  4. js闭包之初步理解( JavaScript closure)

    闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解. 要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域, ...

  5. (原创)JS闭包看代码理解

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  6. js闭包理解

    js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...

  7. js闭包理解实例小结

    Js闭包 闭包前要了解的知识  1. 函数作用域 (1).Js语言特殊之处在于函数内部可以直接读取全局变量 <script type="text/javascript"> ...

  8. Js闭包的用途

    本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...

  9. js闭包和ie内存泄露原理

    也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ...

  10. js闭包(closure),个人理解

    一.闭包概念理解 各种专业文献上对js"闭包"(closure)定义非常抽象,贼难看懂.我的理解是,闭包就是能够读取某函数内部变量的函数.由于在Javascript语言中只有在函数 ...

随机推荐

  1. thinkjs系统服务启动

  2. [转]一次Delete&Insert引发的Mysql死锁

    近日遇到一个比较奇怪的deadlock错误, 错误详情: Deadlock found when trying to get lock; try restarting transaction; nes ...

  3. django 'set' object does not support indexing

    在定义Model之后使用syncdb 同步的时候报出这个错误,检查之后发现是用错了.在model的Meta里面,排序这些用的应该是 ordering = ['last','first','middle ...

  4. 常用SQL语句集锦

    MySQL适用 1.如图所示,根据Coord字段内容填充X/Y字段,并调整Coord字段格式(Coord字段原为[Latitude,Longitude]格式,需要将其调整为[Longitude,Lat ...

  5. android开发内存优化之软引用

    所有Android的开发者一定都遇到过内存溢出这个头疼的问题,一旦出现这个问题,很难直接确定我们的应用是那里出了问题,要想定位问题的原因,必须通过一些内存分析工具和强大的经验积累才能快速的定位到问题具 ...

  6. java简答题

    1.什么是java的平台无关性? Java源文件被编译成字节码的形式,无论在什么系统环境下,只要有java虚拟机就能运行这个字节码文件.也就是一处编写,处处运行.这就是java的跨平台性. 2.在一台 ...

  7. Maximum splitting(规律,数论)

    You are given several queries. In the i-th query you are given a single positive integer ni. You are ...

  8. python学习笔记之使用threading模块实现多线程(转)

    综述 Python这门解释性语言也有专门的线程模型,Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来互斥线程对共享资源的访问,但暂时无法利用多处理器的优势 ...

  9. 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下语句:final StringBuffer a=new StringBuffer( ...

  10. 使用百度地图API查地理坐标

    在网络编程中,我们会和API打交道.那么,什么是API?如何使用API呢?本文分享了一下我对API的理解以及百度地图API的使用. API是"Application Programming ...