zoukankan      html  css  js  c++  java
  • 关于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 执行后不会被回收的原因。

  • 相关阅读:
    静态页中利用AJAX.NET实现无刷新页面
    先写一个用ajax开发webgis的JS暂停函数问题!
    AJAX.NET用户开发指南
    如何解决“未能在设计视图中打开,在中以不同方式将值括起来
    VB 各种进制相互转换大全
    Ajax学习资源大全
    vb+MAPX开发打开ACESS数据库并于里面的X,Y 数据绑定
    C#区分中英文统计字符串的长度
    DataList小结
    datagrid出现分页符号,却不能切换
  • 原文地址:https://www.cnblogs.com/czf-zone/p/3203923.html
Copyright © 2011-2022 走看看