精华内容
下载资源
问答
  • tr闭包_关于闭包

    2021-01-12 22:59:08
    卡尔维诺中文站留言板这个帖子专门用作卡尔维诺中文站的留言板,...学习Javascript闭包(Closure) - 阮一峰的网络日志a.bshareDiv,#bsPanel,#bsMorePanel,#bshareF{border:none;background:none;padding:0;margin:0...

    卡尔维诺中文站留言板

    这个帖子专门用作卡尔维诺中文站的留言板,欢迎大家留言和提问。...

    阮一峰

    2007-01-04T18:54:26+08:00

    -->学习Javascript闭包(Closure) - 阮一峰的网络日志

    a.bshareDiv,#bsPanel,#bsMorePanel,#bshareF{border:none;background:none;padding:0;margin:0;font:12px Helvetica,Calibri,Tahoma,Arial,宋体,sans-serif;line-height:14px;}#bsPanel div,#bsMorePanel div,#bshareF div{display:block;}.bsRlogo .bsPopupAwd,.bsRlogoSel .bsPopupAwd,.bsLogo .bsPopupAwd,.bsLogoSel .bsPopupAwd{line-height:16px !important;}a.bshareDiv div,#bsFloatTab div{*display:inline;zoom:1;display:inline-block;}a.bshareDiv img,a.bshareDiv div,a.bshareDiv span,a.bshareDiv a,#bshareF table,#bshareF tr,#bshareF td{text-decoration:none;background:none;margin:0;padding:0;border:none;line-height:1.2}a.bshareDiv span{display:inline;float:none;}div.buzzButton{cursor:pointer;font-weight:bold;}.buzzButton .shareCount a{color:#333}.bsStyle1 .shareCount a{color:#fff}span.bshareText{white-space:nowrap;}span.bshareText:hover{text-decoration:underline;}a.bshareDiv .bsPromo,div.bshare-custom .bsPromo{display:none;position:absolute;z-index:100;}a.bshareDiv .bsPromo.bsPromo1,div.bshare-custom .bsPromo.bsPromo1{width:51px;height:18px;top:-18px;left:0;line-height:16px;font-size:12px !important;font-weight:normal !important;color:#fff;text-align:center;background:url(http://static.bshare.cn/frame/images/bshare_box_sprite2.gif) no-repeat 0 -606px;}div.bshare-custom .bsPromo.bsPromo2{background:url(http://static.bshare.cn/frame/images/bshare_promo_sprite.gif) no-repeat;cursor:pointer;}

    .bsBox{display:none;z-index:100000001;font-size:12px;background:url(http://static.bshare.cn/frame/images//background-opaque-dark.gif) !important;padding:6px !important;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}.bsClose{_overflow:hidden;cursor:pointer;position:absolute;z-index:10000000;color:#666;font-weight:bold;font-family:Helvetica,Arial;font-size:14px;line-height:20px;}.bsTop{color:#666;background:#f2f2f2;height:24px;line-height:24px;border-bottom:1px solid #e8e8e8;}.bsTop span{float:left;}.bsFrameDiv,#bsMorePanel{border:none;background:#fff;}.bsReturn{float:right;*margin-right:20px;margin-right:36px;text-align:right;cursor:pointer;line-height:24px;color:#666;opacity:0.5;}#bsReturn:hover{text-decoration:underline;opacity:1;}

    div.bsClear{clear:both;height:0;line-height:0;overflow:hidden;font-size:0;}.bsSearchDiv{padding:5px 15px;background-color:#fafafa;}.bFind-wrapper-top{background:#fff;border-color:#ccc #aaa #aaa #ccc;border-style:solid;border-width:1px;height:16px;padding:4px;margin:0;}.bFind-wrapper-top input{padding:0 !important;border:none !important;box-shadow:none !important;line-height:16px !important;}.bFind-placeholder{background:url("http://static.bshare.cn/css/images/search-icon.gif") no-repeat;display:block;float:left;height:16px;width:16px;}.bFind{background:none;border:none;float:left;font-size:11px !important;height:16px !important;margin-left:3px;outline:none;padding:0;width:400px;}.bsPlatDiv{height:322px;background:#fff;overflow:auto;padding:0 15px;}#bsLogoList{display:block;list-style:none;overflow:hidden;margin:0;padding:0;}#bsLogoList li{float:left;display:inline-block;width:71px;text-align:center;font-size:12px;height:80px;margin:0 !important;}#bsLogoList .bsPlatIcon{cursor:pointer;display:block !important;text-align:center;}#bsLogoList .bsPlatImg{width:32px;height:32px;border:none !important;display:inline-block;}#bsLogoList .bsPlatImg:hover{-moz-border-radius:7px;-webkit-border-radius:7px;border-radius:7px;box-shadow:0 0 15px #a7a8ac;}#bsLogoList .bsPlatName{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;text-align:center;color:#333 !important;margin-top:2px;line-height:140%;*width:70px;}#bsLogoList .bsPromoM{text-align:center;}.bsFooterDiv{height:24px;line-height:24px;padding:0 15px;border-top:1px solid #e8e8e8;background:#f2f2f2;text-align:right;}a.bsLogoLink{color:#666;}.bsLogoLink:hover{text-decoration:underline;}.bsPromoM{background:url(http://static.bshare.cn/frame/images//bshare_box_sprite2.gif) no-repeat top left;}.bsNew,.bsHot,.bsRec,.bsAwd{background-position:0 -552px;width:19px;margin:5px auto 1px;line-height:16px;height:18px;font-size:12px;color:#fff;overflow:hidden;}.bsNew{background-position:0 -570px;}.bsRec{width:30px;background-position:0 -588px;}.bsAwd{background:url(http://static.bshare.cn/frame/images//promot/promote.gif) no-repeat;}

    a.bsSiteLink{text-decoration:none;color:#666;}a.bsSiteLink:hover{text-decoration:underline;}a.bshareDiv{overflow:hidden;height:16px;line-height:18px;font-size:14px;color:#333;padding-left:0;}a.bshareDiv:hover{text-decoration:none;}div.bsTitle{padding:0 8px;border-bottom:1px solid #e8e8e8;color:#666;background:#f2f2f2;text-align:left;}div.buzzButton{cursor:pointer;}div.bsRlogo,div.bsRlogoSel{width:68px;float:left;margin:0;padding:2px 0;}div.bsRlogo a,div.bsRlogoSel a{float:left;}div.bsLogo,div.bsLogoSel{float:left;width:111px;text-align:left;height:auto;padding:2px 4px;margin:2px 0;white-space:nowrap;overflow:hidden;}div.bsLogoSel,div.bsRlogoSel{border:1px solid #ddd;background:#f1f1f1;}div.bsLogo,div.bsRlogo{border:1px solid #fff;background:#fff;}div.bsLogo a,div.bsLogoSel a{display:block;height:16px;line-height:16px;padding:0 0 0 24px;text-decoration:none;float:left;overflow:hidden;}div.bsLogoSel a,div.bsRlogoSel a{color:#000;border:none;}div.bsLogo a,div.bsRlogo a{color:#666;border:none;}div.bsLogoLink{width:121px;overflow:hidden;background:#FFF;float:left;margin:3px 0;}#bsLogin{float:right;text-align:right;overflow:hidden;height:100%;}#bsPanel{position:absolute;z-index:100000000;font-size:12px;width:258px;background:url(http://static.bshare.cn/frame/images/background-opaque-dark.png) !important;padding:6px !important;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}div.bsClear{clear:both;height:0;line-height:0;font-size:0;overflow:hidden;}div.bsPopupAwd{background:url(http://static.bshare.cn/frame/images//bshare_box_sprite2.gif) no-repeat top left;background-position:0 -624px;width:18px;padding-left:3px;text-align:center;float:left;margin-left: 2px;height:15px;font-size:12px;color:#fff;overflow:hidden;}div.bsRlogo .bsPopupAwd,div.bsRlogoSel .bsPopupAwd{float:left;margin:5px 0 0 -14px;}

    a.bsSiteLink{text-decoration:none;color:#666;}a.bsSiteLink:hover{text-decoration:underline;}a.bshareDiv{overflow:hidden;height:16px;line-height:18px;font-size:14px;color:#333;padding-left:0;}a.bshareDiv:hover{text-decoration:none;}div.bsTitle{padding:0 8px;border-bottom:1px solid #e8e8e8;color:#666;background:#f2f2f2;text-align:left;}div.buzzButton{cursor:pointer;}div.bsRlogo,div.bsRlogoSel{width:68px;float:left;margin:0;padding:2px 0;}div.bsRlogo a,div.bsRlogoSel a{float:left;}div.bsLogo,div.bsLogoSel{float:left;width:111px;text-align:left;height:auto;padding:2px 4px;margin:2px 0;white-space:nowrap;overflow:hidden;}div.bsLogoSel,div.bsRlogoSel{border:1px solid #ddd;background:#f1f1f1;}div.bsLogo,div.bsRlogo{border:1px solid #fff;background:#fff;}div.bsLogo a,div.bsLogoSel a{display:block;height:16px;line-height:16px;padding:0 0 0 24px;text-decoration:none;float:left;overflow:hidden;}div.bsLogoSel a,div.bsRlogoSel a{color:#000;border:none;}div.bsLogo a,div.bsRlogo a{color:#666;border:none;}div.bsLogoLink{width:121px;overflow:hidden;background:#FFF;float:left;margin:3px 0;}#bsLogin{float:right;text-align:right;overflow:hidden;height:100%;}#bsPanel{position:absolute;z-index:100000000;font-size:12px;width:258px;background:url(http://static.bshare.cn/frame/images/background-opaque-dark.png) !important;padding:6px !important;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}div.bsClear{clear:both;height:0;line-height:0;font-size:0;overflow:hidden;}div.bsPopupAwd{background:url(http://static.bshare.cn/frame/images//bshare_box_sprite2.gif) no-repeat top left;background-position:0 -624px;width:18px;padding-left:3px;text-align:center;float:left;margin-left: 2px;height:15px;font-size:12px;color:#fff;overflow:hidden;}div.bsRlogo .bsPopupAwd,div.bsRlogoSel .bsPopupAwd{float:left;margin:5px 0 0 -14px;}

    学习Javascript闭包(Closure)

    bShare.addEntry({ title: document.getElementById("page-title").innerHTML,url:window.location.href});

    作者: 阮一峰

    日期: 2009年8月30日

    包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

    下面就是我的学习笔记,对于Javascript初学者应该是很有用的。

    一、变量的作用域

    要理解闭包,首先必须理解Javascript特殊的变量作用域。

    变量的作用域无非就是两种:全局变量和局部变量。

    Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

    var n=999;

    function f1(){    alert(n);  }

    f1(); // 999

    另一方面,在函数外部自然无法读取函数内的局部变量。

    function f1(){    var n=999;  }

    alert(n); // error

    这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

    function f1(){    n=999;  }

    f1();

    alert(n); // 999

    二、如何从外部读取局部变量?

    出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

    那就是在函数的内部,再定义一个函数。

    function f1(){

    var n=999;

    function f2(){      alert(n); // 999    }

    }

    在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

    既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

    function f1(){

    var n=999;

    function f2(){      alert(n);    }

    return f2;

    }

    var result=f1();

    result(); // 999

    三、闭包的概念

    上一节代码中的f2函数,就是闭包。

    各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。

    由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

    所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

    四、闭包的用途

    闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    怎么来理解这句话呢?请看下面的代码。

    function f1(){

    var n=999;

    nAdd=function(){n+=1}

    function f2(){      alert(n);    }

    return f2;

    }

    var result=f1();

    result(); // 999

    nAdd();

    result(); // 1000

    在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

    为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

    这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

    五、使用闭包的注意点

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

    2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    六、思考题

    如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。

    代码片段一。

    var name = "The Window";

    var object = {    name : "My Object",

    getNameFunc : function(){      return function(){        return this.name;      };

    }

    };

    alert(object.getNameFunc()());

    代码片段二。

    var name = "The Window";

    var object = {    name : "My Object",

    getNameFunc : function(){      var that = this;      return function(){        return that.name;      };

    }

    };

    alert(object.getNameFunc()());

    展开全文
  • js的闭包是学习js过程中的重点,但是不得不说也是一个难点呀,其涉及到了js中的很多概念。我在学习js中也遇到了很多问题,这篇文章算是一个对闭包的总结,文章主要内容为闭包的基本知识点与对其理解上的一些难点的...

    js的闭包是学习js过程中的重点,但是不得不说也是一个难点呀,其涉及到了js中的很多概念。我在学习js中也遇到了很多问题,这篇文章算是一个对闭包的总结,文章主要内容为闭包的基本知识点与对其理解上的一些难点的讲解。

    闭包是什么?

    闭包就是嵌套在函数里面的内部函数,并且该内部函数可以访问外部函数中声明的所有局部变量、参数和其他内部函数。当该内部函数在外部函数外被调用,就生成了闭包。注意这里的调用两个字,如果内部函数没有被外部函数返回的话就不能被调用了。

    functionouterFun()

    {var a=0;functioninnerFun()

    {

    a++;

    alert(a);

    }

    }

    innerFun();

    这里的innerFun就不能被外部调用,因为其在outerFun中定义的,作用域为outerFun的范围。

    functionouterFun()

    {var a=0;functioninnerFun()

    {

    a++;

    alert(a);

    }return innerFun; //注意这里

    }

    在outerFun内部将innerFun返回到外部就能在外部调用innerFun了。

    为什么内部定义的函数只有在返回到外部后才能使用?

    这与js的运行机制有关:

    如果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。

    当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。

    当执行函数a的时候,a会进入相应的执行环境(excution context)。

    在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。

    然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。

    下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。

    最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。

    到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给全局变量c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。

    在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,而c又一直存在,这就是为什么函数a执行后不会被回收的原因。

    当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:

    如图所示,当在函数b中访问一个变量的时候,搜索顺序是:

    先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依次查找,直到找到为止。

    如果函数b存在prototype原型对象,则在查找完自身的活动对象后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。

    如果整个作用域链上都无法找到,则返回undefined。

    让我们说的更透彻一些。所谓“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量。这使得只要目标 对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新的值,和上次那次调用的是各自独立的。

    下面利用一个实际例子进行分析。

    id.οnclick= function(){ alert(i); }

    }

    }//-->

    • aa
    • aa
    • aa

    这段代码的实际效果是无论点击哪一个标签都是现实“4”。因为在onload函数后执行完后i的值就是4了,中间变化的过程值没有被内存存储。闭包允许内层函数引用父函数中的变量,但是该变量是最终值

    id.οnclick= (function(i) {return function() {

    alert(i);

    }

    })(i);

    }

    }//-->

    • aa
    • aa
    • aa

    而这段代码的实际效果为点击标签其会显示对应的数字,因为在onload执行的过程中利用了闭包,将每次调用函数产生的结果都保存在了内存(全局变量c)中,三个不同的i值被单独存储了。

    闭包的作用?

    在动态执行环境中,数据实时地发生变化,为了保持这些非持久型变量的值,我们用闭包这种载体来存储这些动态数据。这就是闭包的作用。也就说遇到需要存储动态变化的数据或将被回收的数据时,我们可以通过外面再包裹一层函数形成闭包来解决。闭包并不能存储动态值,需要在全局作用域中调用才能实现存储功能。

    展开全文
  • tr闭包_什么是闭包?

    2021-01-12 22:59:06
    闭包就是能够读取其他函数内部变量的62616964757a686964616fe58685e5aeb931333433626565函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质...

    闭包就是能够读取其他函数内部变量的62616964757a686964616fe58685e5aeb931333433626565函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

    简单介绍

    闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。在PHP、Scala、Scheme、Common

    Lisp、Smalltalk、Groovy、JavaScript、Ruby、 Python、Go、Lua、objective c、swift

    以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。

    本质

    集合 S 是闭集当且仅当 Cl(S)=S(这里的cl即closure,闭包)。特别的,空集的闭包是空集,X 的闭包是 X。集合的交集的闭包总是集合的闭包的交集的子集(不一定是真子集)。有限多个集合的并集的闭包和这些集合的闭包的并集相等;零个集合的并集为空集,所以这个命题包含了前面的空集的闭包的特殊情况。无限多个集合的并集的闭包不一定等于这些集合的闭包的并集,但前者一定是后者的父集。

    若 A 为包含 S 的 X 的子空间,则 S 在 A 中计算得到的闭包等于 A 和 S 在 X 中计算得到的闭包(Cl_A(S) = A ∩ Cl_X(S))的交集。特别的,S在 A 中是稠密的,当且仅当 A 是 Cl_X(S) 的子集。

    cl(S) 是 S 的闭父集。

    cl(S) 是所有包含 S 的闭集的交集。

    cl(S) 是包含 S 的最小的闭集。

    集合 S 是闭集,当且仅当 S = cl(S)。

    若 S 是 T 的子集,则 cl(S) 是 cl(T) 的子集。

    若 A 是闭集,则 A 包含 S 当且仅当 A 包含 cl(S)。

    有时候,上述第二或第三条性质会被作为拓扑闭包的定义。

    在第一可数空间(如度量空间)中,cl(S) 是所有点的收敛数列的所有极限。

    举例说明

    闭包 (closure)是个精确但又很难解释的电脑名词。在 Perl 里面,闭包是以 匿名函数的形式来实现,具有持续参照位于该函数范围之外的文字式变数值的能力。这些外部的文字变数会神奇地保留它们在闭包函数最初定义时的值 (深连结)。

    如果一个程式语言容许函数递回另一个函数的话 (像 Perl

    就是),闭包便具有意义。要注意的是,有些语言虽提供匿名函数的功能,但却无法正确处理闭包; Python

    这个语言便是一例。如果要想多了解闭包的话,建议你去找本功能性程式 设计的教科书来看。Scheme这个语言不仅支持闭包,更鼓励多加使用。

    以下是个典型的产生函数的函数:

    sub add_function_generator {

    return sub { shift + shift };

    }

    $add_sub = add_function_generator();

    $sum = &$add_sub(4,5); # $sum是 9了

    闭包用起来就像是个函数样板,其中保留了一些可以在稍後再填入的空格。add_function_generator() 所递回的匿名函数在技术上来讲并不能算是一个闭包, 因为它没有用到任何位在这个函数范围之外的文字变数。

    把上面这个例子和下面这个make_adder()函数对照一下,下面这个函数所递回的匿名函数中使用了一个外部的文字变数。这种指明外部函数的作法需要由 Perl递回一个适当的闭包,因此那个文字变数在匿名函数产生之时的值便永久地被锁进闭包里。

    sub make_adder {

    my $addpiece = shift;

    return sub { shift + $addpiece };

    }

    $f1 = make_adder(20);

    $f2 = make_adder(555);

    这样一来&$f1($n) 永远会是 20加上你传进去的值$n ,而&$f2($n) 将 永远会是 555加上你传进去的值$n。$addpiece的值会在闭包中保留下来。

    闭包在比较实际的场合中也常用得到,譬如当你想把一些程式码传入一个函数时:

    my $line;

    timeout(30,sub { $line = });

    如果要执行的程式码当初是以字串的形式传入的话,即'$line = ' ,那么timeout() 这个假想的函数在回到该函数被呼叫时所在的范围后便无法再截取$line这个文字变数的值了。

    语法结构

    Groovy

    闭包(Closure)是Java所不具备的语法结构(JAVA8增加了对闭包的支持)。闭包就是一个代码块,用“{ }”包起来。此时,程序代码也就成了数据,可以被一个变量所引用(与C语言的函数指针比较类似)。闭包的最典型的应用是实现回调函数(callback)。Groovy的API大量使用闭包,以实现对外开放。闭包的创建过程很简单,例如:

    { 参数 ->

    代码...

    }

    参考下面的例子代码,定义了c1和c2两个闭包,并对它们进行调用:

    def c1 = { println it }

    def c2 = { text -> println text }

    c1.call("content1") //用call方法调用闭包

    c2("content2") //直接调用闭包

    “->;”之前的部分为闭包的参数,如果有多个参数,之间可用逗号分割;“->;”之后的部分为闭包内的程序代码。如果省略了“->;”和它之前的部分,此时闭包中代码,可以用名为“it”的变量访问参数。

    闭包的返回值和函数的返回值定义方式是一样的:如果有return语句,则返回值是return语句后面的内容;如果没有return语句,则闭包内的最后一行代码就是它的返回值。[2]

    Lua

    当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征在lua中我们称作词法定界。虽然这看起来很清楚,事实并非如此,词法定界加上第一类函数在编程语言里是一个功能强大的概念,很少语言提供这种支持。

    下面看一个简单的例子,假定有一个学生姓名的列表和一个学生名和成绩对应的表;想根据学生的成绩从高到低对学生进行排序,可以这样做:

    names = {"Peter","Paul","Mary"}

    grades = {Mary = 10,Paul = 7,Peter = 8}

    table.sort(names,function (n1,n2)

    return grades[n1] > grades[n2] -- compare the grades

    end)

    假定创建一个函数实现此功能:

    function sortbygrade (names,grades)

    table.sort(names,function (n1,n2)

    return grades[n1] > grades[n2] --compare the grades

    end)

    Scheme

    其他编程的语言主要采用的是闭包的第二种意义(一个与闭包毫不相干的概念):闭包也算一种为表示带有自由变量的过程而用的实现技术。但Scheme的术语“闭包”来自抽象代数。在抽象代数里,一集元素称为在某个运算(操作)之下封闭,如果将该运算应用于这一集合中的元素,产生出的仍然是该集合里的元素。

    用Scheme的序对举例,为了实现数据抽象,Scheme提供了一种称为序对的复合结构。这种结构可以通过基本过程cons构造出来。过程cons取两个参数,返回一个包含这两个参数作为其成分的复合数据对象。请注意,一个序对也算一个数据对象。进一步说,还可以用cons去构造那种其元素本身就是序对的序对,并继续这样做下去。

    (define x (cons 1 2)) //构造一个x序对,由1,2组成

    (define y (cons 3 4))

    (define z (cons x y))

    Scheme可以建立元素本身也算序对的序对,这就是表结构得以作为一种表示工具的根本基础。我们将这种能力称为cons的闭包性质。一般说,某种组合数据对象的操作满足闭包性质,那就是说,通过它组合起数据对象得到的结果本身还可以通过同样的操作再进行组合。闭包性质是任何一种组合功能的威力的关键要素,因为它使我们能够建立起层次性结构,这种结构由一些部分构成,而其中的各个部分又是由它们的部分构成,并且可以如此继续下去。

    创建

    在Javascript中闭包的创建过程,如以下程序所示。

    代码

    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外的一个变量引用的时候,就创建了一个闭包。

    作用

    简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。

    在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。

    那 么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引 用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被回收。

    例子

    例1

    模拟私有变量:

    function Counter(start){

    var count = start;

    return{

    increment:function(){

    count++;

    },

    get:function(){

    return count;

    }

    }

    }

    var foo =Counter(4);

    foo.increment();

    foo.get();// 5

    这里,Counter 函数返回两个闭包,函数 increment 和函数 get。 这两个函数都维持着对外部作用域 Counter 的引用,因此总可以访问此作用域内定义的变量count。

    objective c的闭包(block)

    objective c

    中的的闭包,是通过block实现的。Apple在C,Objective-C和C++中扩充了Block这种文法的,并且在GCC4.2中进行了支持。你可以把它理解为函数指针,匿名函数,闭包,lambda表达式,这里暂且用块对象来表述,因为它们之间还是有些许不同的。

    如果以内联方式使用块对象,则无需声明。块对象声明语法与函数指针声明语法相似,但是块对象应使用脱字符(^)而非星号指针 (*)。下面的代码声明一个aBlock变量,它标识一个需传入三个参数并具有float返回值的块。

    float (^aBlock)(const int*, int, float);

    例2

    下面是一个使用闭包简单的例子,模拟一个计数器,通过将整型包裹为一个列表的单一元素来模拟使看起来更易变:

    函数counter()所作的唯一一件事就是接受一个初始化的值来计数,并将该值赋给列表count成员,然后定义一个内部函数incr()。通过内部函数使用变量count,就创建了一个闭包。最魔法的地方是counter()函数返回一个incr(),一个可以调用的函数对象。

    运行:

    >>> c = counter⑸

    >>> type(c)

    >>> print c()6

    >>> print c()

    7

    >>> c2 = counter(99)

    100

    >>> print c()

    8

    微观世界

    如 果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(execution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。

    1、当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。

    2、当函数a执行的时候,a会进入相应的执行环境(execution context)。

    3、在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。

    4、然后执行环境会创建一个活动对象(call

    object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。

    5、下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。

    6、最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。

    到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。

    当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:

    当在函数b中访问一个变量的时候,搜索顺序是先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依次查找,直到找到为止。如果整个作用域链上都无法找到,则返回undefined。如果函数b存在prototype原型对象,则在查找完自身的活动对象

    后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。

    应用场景

    1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。

    2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。

    以上两点是闭包最基本的应用场景,很多经典案例都源于此。

    回收机制

    在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

    匿名内部

    在Python中的闭包(Closure)

    学过Java GUI编程的人都知道定义匿名内部类是注册监听等处理的简洁有效手段,闭包的定义方式有点类似于这种匿名内部类,

    但是闭包的作用威力远远超过匿名内部类,这也是很多流行动态语言选择闭包的原因,相信你在JavaScript中已经了解它的神奇功效了。

    度量空间

    对欧几里德空间的子集 S,x 是 S 的闭包点,若所有以 x 为中心的开球都包含 S 的点(这个点也可以是 x)。

    这个定义可以推广到度量空间 X 的任意子集 S。具体地说,对具有度量

    d 的度量空间 X,x 是 S 的闭包点,若对所有 r > 0,存在 y 属于 S,使得距离 d(x,y) < r(同样的,可以是

    x = y)。另一种说法可以是,x 是 S 的闭包点,若距离 d(x,S) := inf{d(x,s) : s 属于 S} = 0(这里

    inf 表示下确界)。

    这个定义也可以推广到拓扑空间,只需要用邻域替代“开球”。设 S 是拓扑空间 X 的子集,则 x 是 S 的闭包点,若所有 x 邻域都包含 S 的点。注意,这个定义并不要求邻域是开的。

    离散数学

    离散数学中,一个关系R的闭包,是指加上最小数目的有序偶而形成的具有自反性,对称性或传递性的新的有序偶集,此集就是关系R的闭包。

    设R是集合A上的二元关系,R的自反(对称、传递)闭包是满足以下条件的关系R':

    (i)R'是自反的(对称的、传递的);

    (ii)R'⊇R;

    (iii)对于A上的任何自反(对称、传递)关系R",若R"⊇R,则有R"⊇R'。

    R的自反、对称、传递闭包分别记为r(R)、s(R) 和t(R)。

    性质1

    集合A上的二元关系R的闭包运算可以复合,例如:

    ts(R)=t(s(R))

    表示R的对称闭包的传递闭包,通常简称为R的对称传递闭包。而tsr(R)则表示R的自反对称传递闭包。

    性质2

    设R是集合A上的二元关系,则有

    (a)如果R是自反的,那么s(R)和t(R)也是自反的;

    (b)如果R是对称的,那么r(R)和t(R)也是对称的;

    (c)如果R是传递的,那么r(R)也是传递的。

    性质3

    设R是集合A上的二元关系,则有

    (a)rs(R)=sr(R);

    (b)rt(R)=tr(R);

    (c)ts(R)⊇ st(R)。

    使用注意点

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

    (2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果把父函数当作对象(object)使用,把闭包当作它的公用方法(Public

    Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    点集拓扑系列

    展开全文
  • 这篇文章其实是要讲闭包的一些初级应用,但是为了将闭包,我们还是从嵌套函数开始说吧,纵使所有的JavaScript函数都可以说是闭包,但是只有当一个嵌套函数被导出到它所定义的作用域之外时,这种闭包才是有趣的。...

    这篇文章其实是要讲闭包的一些初级应用,但是为了将闭包,我们还是从嵌套函数开始说吧,纵使所有的JavaScript函数都可以说是闭包,但是只有当一个嵌套函数被导出到它所定义的作用域之外时,这种闭包才是有趣的。

    【嵌套函数】

    JavaScript允许嵌入的函数,允许函数用作数据,并且在函数词法作用域下面,可以产生与传统面向对象语言不同的惊人地方。

    首先,JavaScript的函数是通过词法来划分作用域的,而不是动态的划分作用域的,于是,函数的是在定义它们的作用域中运行,而不是在执行它们的作用域中运行,所以,当嵌套函数和它的外围函数定义在同一个词法作用域中的时候,是很容易理解的。比如下面很平淡无奇的代码:

    varx='global';functionf () {varx='local';functiong() {

    alert(x);

    }

    g();

    }

    f();//'local'

    当f()调用的时候,作用域链可以理解为由两部分组成,包含f这一调用的调用对象,然后后面是全局对象。此时查找x的值,会先从f的调用对象中查找,如果没有,再查找后面全局对象中x。同理,g因为是f的一个嵌套函数,那么,g调用的时候,作用域链应该就是由三部分组成了,g的调用对象,f的调用对象,和全局对象。函数g是要输出x的值,所以会先在g的调用对象中查找x的值,g中没有定义,接下来查找外围f调用对象中x的定义,于是找到了x='local',那么就会输出x,而不会继续往下查找全局对象了。  如果f中也没定义x的值,那么就会继续查找作用域链后面的全局对象,结果就是global了。如果全局对象中也没定义,那么自然就是undefined。

    好了,我们对作用域链有了个初步的理解,同时我们知道,闭包有两个比较常用的用途,一个是可以利用它访问到局部变量,另一个是可以把它外围作用域中的变量值存储在内存中而不在函数调用完毕后就销毁。

    下面接着看一个平淡无奇的例子,或许可以帮助理解为什么闭包可以把外部变量值保存在内存中了。

    functionmakeFunc (x) {returnfunction() {returnx++}

    }vara=[makeFunc(0), makeFunc(1), makeFunc(2)];

    alert(a[0]());

    alert(a[1]());

    alert(a[2]());

    执行结果为0,1,2 ;也没有什么特别的地方,这也是严格的词法作用域的正常表现。每次makeFunc调用完毕后,它的调用对象会从作用域链中移除,再没有任何对它的引用,最终通过垃圾收集而完结。说的详细一点,我们可以这样理解。

    makeFunc每次调用的时候,会为他创建一个调用对象放置到作用域链中。针对makeFunc这个函数而言,这个调用对象包含一个属性x(也就是函数的参数,因为函数参数可以看做调用对象的一个属性),makeFunc会返回一个匿名嵌套函数的引用,接下来这个匿名嵌套函数执行,又会创建一个调用对象,放置到作用域链中,匿名函数返回x的值,(注意:匿名函数的调用对象中是没有x的定义的,于是它会引用到它外围的函数makeFunc的调用对象,访问到x)然后x加1,至此,匿名函数执行完毕,它调用对象从作用域链中移除, 然后makeFunc也执行完毕,makeFunc调用对象也被移除。由于它的调用对象中包含x,所以x也随着它的销毁而销毁。不会保存下来。

    以上就是函数的详细的执行过程,请仔细理解后看看下面改动的代码:

    varx=0;functionmakeFunc () {returnfunction() {returnx++}

    }vara=[makeFunc(), makeFunc(), makeFunc()];

    alert(a[0]());

    alert(a[1]());

    alert(a[2]());

    现在x是一个全局变量了,执行结果为0,1,2;但是这个结果就与上面的有些不同了。下面我们还是从作用域链的方向来理解这个结果产生的原因。

    同样,makeFunc每次调用的时候会创建一个调用对象到作用域链中,由于它返回内部嵌套函数的引用,所以内部嵌套函数开始执行,又创建一个嵌套函数的调用对象到作用域链。然后返回x的值,注意,这里就不同了,嵌套函数的调用对象中没有x,它外围的makeFunc的调用对象中也没有x,只能接着往下查找到全局对象中,在全局对象中找到了x的定义,于是正常执行,返回x的值,x加1,然后嵌套函数完毕,调用对象移除,接着makeFunc完毕,调用对象也移除,可是因为他们的调用对象中都没有x,他们的调用对象销毁根本不会影响到x。于是,全局变量x值的改变就这样被保存下来了。

    注意,上面说的访问外围的调用对象只是为了帮助理解而不严格的说法,JavaScript不会以任何方式直接访问调用对象,但是,它定义的属性作为调用对象中作用域链的一部分,还是“活的”。另外,如果一个外围函数包含了两个或多个嵌套函数都对全局对象有引用,那么这些嵌套函数都共享同一个全局调用对象,并且其中一个对全局对象的改变对其他的都是可见的。

    好了,在JavaScript里,函数是将要执行的代码以及执行这些代码的作用域构成的一个综合体,广义的说,我们就可以把这种代码和作用域的综合体叫做闭包。

    【闭包】

    我们偶尔需要写一个需要通过调用来记住一个变量值的函数。于是,如果我们了解了作用域,就会知道,局部变量是很难做到的,因为函数的调用对象不能在调用后一直维持。全局变量可以做到,就如上面的例子一样,但是这样很容易造成全局变量污染。既然调用对象不能维持,那么我们不把值保存在调用对象中不就行了?!所以,下面是实现的一种方法:用函数对象自身的属性来保存。

    uniqueID=function() {if(!arguments.callee.id) arguments.callee.id=0;returnarguments.callee.id++;

    }

    alert(uniqueID());//0alert(uniqueID());//1

    如上,因为函数本身就是一个对象,所以,我们用它自身的一个属性来保存是可行的,但是这样做有一个问题,就是任何人在任何时候都可以通过unqueID.id强制访问到我们原本保存到的值并作出修改。这是我们不愿看到的。

    所以,通常,我们使用闭包来实现这件事。如下:

    _uniqueID=(function(){varid=0;returnfunction() {returnid++}

    })();

    alert(_uniqueID());//0alert(_uniqueID());//1

    同样,我们也用作用链域来解释下结果。注意到_uniqueID本身就是一个匿名函数,它内部又有个匿名嵌套函数,我们直接调用的是_uniqueID(),也就是说,我们直接调用的其实是_uniqueID内部的嵌套函数,而它本身的调用对象没有定义id,于是引用外围的调用对象中的id,并返回,id加1,执行完毕,内层嵌套函数调用对象移出作用域链。而外围的id并没有被销毁,于是就这样保存了下来。

    有人可能会疑惑,不是说调用对象在函数执行完毕后就移除了作用域链吗,外围匿名函数(function(){})();也是调用完毕了的,应该调用对象也没了才对。

    是的,调用对象是在当前函数执行完毕后就结束引用,但是这里不要误解了上面_uniqueID()的调用,他并不是直接调用的外围函数,而是调用的嵌套函数,嵌套函数的作用域链是包含外围函数的作用域链的。所以在它的调用对象移除作用域链的时候是能够访问到这条作用域链上其他对象的属性并改变的。

    闭包本身就是个难以理解但是又非常有用的东西,希望能对有需要的人一些帮助吧。此外,资历所限,本人理解也可能有误,如发现,敬请指正。

    来源: http://www.cnblogs.com/hongru/archive/2010/10/30/1865041.html

    展开全文
  • 一、闭包的含义1.设计一个table,使鼠标点击哪行就能显示行数:错误js代码:var consle=document.getElementById("consle");var tab=document.getElementById("table");var trs=document.getElementByTagname("tr");...
  • 什么是闭包最近更新: 2014年02月28日14:39:58 (最新地址)一、一个问题例一:假设要写动态生成HTML的函数,HTML有一部分是固定的。方案①function buildHtml(args) {var template = ['','','','',''];template[1] = ...
  • 闭包 what 's the fuck闭包,是什么鬼,谁学谁都脑进水!我会用5W3H1TS的方式,去讲闭包1. what一个函数,记住自己定义时的“词法作用域”,就产生了闭包即使此函数在其他地方执行!上一个“词法作用域”的 例子 ,...
  • 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。闭包的特性闭包有三个特性:1.函数嵌套函数2.函数内部可以引用外部的参数和变量3.参数和变量不会被垃圾回收机制回收闭包的...
  • 1 /*2 * 该程序用于计算某个产生式的闭包3 * RexfieldVon4 * 2013年8月9日16:01:385 */6 #include 7 #include 8 #include 910 #ifndef bool11 # define bool char12 #endif1314 #ifndef true15 # define true 116 #...
  • 在前端开发必须知道的JS之原型和继承一文中说过下面写篇闭包,加之最近越来越发现需要加强我的闭包应用能力,所以此文不能再拖了。本文讲的是函数闭包,不涉及对象闭包(如用with实现)。如果你觉得我说的有偏差,欢迎...
  • tr闭包_前端面试题

    2020-12-21 07:27:39
    1.1、前端 MV*框架的意义 早期前端都是比较简单,基本以页面为工作单元,内容以浏览型为主,也偶尔有简单的表单操作,基本不太需要框架。... 太深的嵌套,比如table>tr>td>h3,会导致搜索引擎读取困难,而且,最...
  • 本文讲的是函数闭包,不涉及对象闭包(如用with实现)。如果你觉得我说的有偏差,欢迎拍砖,欢迎指教。一. 闭包的理论首先必须了解以下几个概念:执行环...
  • 一、理论基础知识部分1.1、讲讲输入完网址按下回车,到看到网页这个过程中发生了什么a. 域名解析b. 发起TCP的3次握手c. 建立TCP连接后发起http请求d. 服务器端响应http请求,浏览器得到html代码e.... 请求数量:...
  • 一、中文模版中文求职信模板(一)尊敬的先生/小姐:您好!本人欲申请贵公司网站上招聘的网络维护工程师职位。我自信符合贵公司的要求。今年7月,我将从清华大学毕业。我的硕士研究生专业是计算机开发及应用,论文内容...
  • 一、理论知识更多学习内容:我的学习交流群点击:web前端学习交流群1.1、讲讲输入完网址按下回车,到看到网页这个过程中发生了什么a. 域名解析b. 发起TCP的3次握手c. 建立TCP连接后发起http请求d....
  • newdocumentwindow.onload=function(){//鼠标移动改变背景,可以通过给每行绑定鼠标移上事件和鼠标移除事件来改变所在行背景色。vartabletr=document....i{tabletr[i].onmouseover=function(){tabletr[i]....
  • & CSS]1.Doctype? 严格模式与混杂模式-如何触发这两种模式,区分它们有何意义? 首先我讲讲如何触发两种模式: 加入xml头部声明可以触发IE浏览器的Quirks mode,触发之后,浏览器解析方式就和IE5.5一样,拥有IE...
  • 图标是页面中非常友好的附加物,许多网站都会使用各种图标来美化页面样式,给用户提供更好的指引。本文将会和大家一起学习页面图标的发展史,以及当前的最优解决方案。传统图标字体图标SVG 图标传统图标编写图标最...
  • 闭包模拟私有方法 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题 4.2、call 和 apply 的区别是什么? call 和 apply 就是为了改变函数体内部 this 的...
  • 海码学院:前端2019年最专业的学习路线图+海量免费配套资源视频、源码、笔记、开发工具、流行框架、手册、面试宝典资源网盘直接下载资源获取QQ号:8239882111.1、前端 MV*框架的意义早期前端都是比较简单,基本以...
  • TRManager作为所有下载任务的管理者,也可以设置回调 // 回调闭包的参数都是TRManager对象,因为开发者可以通过TRManager对象得到任何相关的信息,把灵活度最大化 // 回调闭包都是在主线程运行 // progress 闭包:...
  • javascript闭包获取table中tr的索引

    千次阅读 2015-05-04 15:10:31
    javascript闭包获取table中tr的索引<!DOCTYPE ...
  • 闭包

    2019-03-14 09:45:49
    &lt;!...-//W3C//DTD XHTML 1.0...http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt
  • 使用javascript闭包获取table标签中tr的索引 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <...
  • js闭包

    2015-05-02 23:49:00
    DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head>...
  • javascript 闭包

    2013-05-13 20:43:00
    DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> ...

空空如也

空空如也

1 2 3 4 5 6
收藏数 108
精华内容 43
关键字:

tr闭包