您的位置:首页 > Web前端 > JavaScript

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

2011-09-04 17:25 459 查看
一.闭包的概念

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

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

二.闭包的作用

简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程

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

那么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会 被b引用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被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("【([^】]+)】");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐