js 闭包的概念 方法链的调用 下拉框测试 表单action数值替换

来源:互联网 发布:ubuntu 16.04 ssd优化 编辑:程序博客网 时间:2024/05/22 00:23
 

一.闭包的概念

其实这句话通俗的来说就是:JavaScript中所有的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实际上是指向了函数bb中用到了变量i,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:

当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个我们通常所谓的闭包

二.闭包的作用

简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c()i都是自加1alerti的值。

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

三闭包的微观世界

四.Js中匿名函数及函数的闭包

4.1 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式
a)这也是最常规的一种

Function double(x){

retrun 2 * x;

}

b)这种方法使用了Function构造函数,把参数列表和函数体都作为字符串,很不方便,不建议使用。

Var double = new Functioni( 'x', 'return 2*x;' );

c)'右边的函数就是一个匿名函数(创建有2中方式)
   var double = function(x){

return x*2;

}
(function(x){

alert(x);

})(1);

4.2匿名函数与闭包

匿名函数最大的用途是创建闭包(这是JavaScript语言的特性之一),并且还可以构建命名空间,以减少全局变量的使用。例如:
var JSON = JSON || {};

(

    function(){

        var f = function(n){

            for(var i=0;i<n;i++){

                   alert(i);

            }

        };

        JSON.f=f;

})();

JSON.f(1);

4.3闭包主意点

主意:闭包允许内层函数引用父函数中的变量,但是该变量是最终值。


你会发现当鼠标移过每一个<li>元素时,总是弹出4,而不是我们期待的元素下标。这是为什么呢?注意事项里已经讲了(最终值)。显然这种解释过于简单,当mouseover事件调用监听函数时,首先在匿名函数( function(){ alert(i); })内部查找是否定义了 i,结果是没有定义;因此它会向上查找,查找结果是已经定义了,并且i的值是4(循环后的i值);所以,最终每次弹出的都是4

解决方案:

var lists = document.getElementsByTagName('li');

for(var i = 0 , len = lists.length ; i < len ; i++ ){

    (function( index ){

        lists[ index ].onmouseover = function(){

            alert( index );    

        };                    

    })( i );

}

 

二、方法链的调用

<script>function ClassA(){this.prop1 = null;this.prop2 = null;this.prop3 = null;}ClassA.prototype = {method1:function(p1){this.prop1 = p1;return this;},method2:function(p2){this.prop2 = p2;return this;},method3:function(p3){this.prop3 = p3;return this;}}function chain(obj){         return function(){             var Self = arguments.callee; //self is function chain.   Self.obj = obj;             if(arguments.length==0){                 return Self.obj;             }              var x = Self.obj[arguments[0]];             //表示构造成一个赋值对象, arguments[0]的值(如值是prop1 )做为对象的一个属性,如下形式           // x = function(p1){          //   this.prop1 = p1;    //属性赋值表达式                                                var a = [].slice.call(arguments,1);           //取arguments 的第一个元素,并转化成一个数组.玩了一个技巧(不推荐)      //var a = [arguments[1]]; //这样写更简单明了。执行等同上面的一句.            x.apply(Self.obj,a);   //Self.obj调用x的属性赋值表达式,把a数组的第一个元素的值,赋给Self.obj同名属性           return Self;         }      }   //定义的function/类ClassB      function ClassB(){         this.prop1 = null;         this.prop2 = null;         this.prop3 = null;      }      ClassB.prototype = {         method1 : function(p1){             this.prop1 = p1;         },         method2 : function(p2){             this.prop2 = p2;         },         method3 : function(p3){             this.prop3 = p3;         },   print : function(){       alert(this.prop1 + " " + this.prop2 + " " + this.prop3);   }    }       var obj = new ClassB();      var objx = chain(obj)('method1',4)('method2',5)('method3',6);    obj.print();       //同上,但推荐采用上面的调用方式。   // objx.obj.print();</script>


 三、下拉框测试

 

<select id="select1" style="height:100px;width:100px;" multiple="multiple"><option value="11" >11111111111</option><option value="22">22222222222</option><option value="33">33333333333</option><option value="44">44444444444</option></select><select id="select2" style="height:100px;width:100px;" multiple="multiple"></select><br/><br/><br/><input type="button" value="选中添加到右边>>" onclick="addright();"/><input type="button" value="<<选中删除到左边" onclick="addleft()"/><input type="button" value="全部添加到右边"  onclick="addAllRight();"/><input type="button" value="<<全部删除到左边" onclick="addAllLeft();"/>
<script>//-------------------------------下拉框测试---------------------------------------------//function addright(){var $select1 = $('#select1 option:selected');$select1.remove().appendTo('#select2');//追加给对方}function addleft(){var $select2 = $('#select2 option:selected');//获得选中选项$select2.remove().appendTo('#select1');}function addAllRight(){var $options1 = $('#select1 option');$options1.appendTo('#select2');}function addAllLeft(){var $options2 = $('#select2 option');//获得全部选项$options2.appendTo('#select1');}function checkSelect(isSelect,msg_select,msg_end){if( typeof(isSelect) == 'undefined' ){alert(msg_end);return false;}if(isSelect == null || isSelect == ""){alert(msg_select);$('#select1').focus();return false;}}</script>

四.表单action数值的替换

var oldaction = document.forms['formChangeEmailAddressName'].getAttribute('action');document.forms['formChangeEmailAddressName'].setAttribute('action','forgotQuestionOrAnswer.action');document.forms['formChangeEmailAddressName'].submit(); document.forms['formChangeEmailAddressName'].setAttribute('action',oldaction);

五、重写alert方法

window.alert = function(n){
    alert(1);
   
}


window.constructor.prototype.alert.call(null,1);

 四.js 正则

【申请号】        200820238191【发明名称】    茶园管理作业机多用底盘String[] list=record.split("【([^】]+)】");