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 );
}
二、方法链的调用
三、下拉框测试
四.表单action数值的替换
五、重写alert方法
window.alert = function(n){
alert(1);
}
window.constructor.prototype.alert.call(null,1);
四.js 正则
其实这句话通俗的来说就是: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("【([^】]+)】");
相关文章推荐
- JSPatch实现原理详解:让JS调用/替换任意OC方法
- js实现接收表单的值并将值拼在表单action后面的方法
- Qt自动填写表单并点击按钮,包括调用js方法
- js实现接收表单的值并将值拼在表单action后面的方法
- 用JS动态改变表单form里的action值属性的两种方法
- action 调用jsp页面的js方法
- A/B 测试的基本概念举例理解以及具体实现方法【传统A/B测试基于后端的 A/B 测试(Back-end AB test),现在基本上基于前端js在客户端进行分流,有更多优点,请看里面】
- js 方法中直接调用action
- 利用js的闭包原理做对象封装及调用方法
- js,ajax调用action并取得返回值页面不刷新的方法
- JS动态改变form表单里的action值属性的方法
- struts2 配置测试ajax时发现action方法调用两次
- js实现接收表单的值并将值拼在表单action后面的方法
- JSPatch实现原理详解:让JS调用/替换任意OC方法
- js replace 全局替换 以表单的方式提交参数 判断是否为ie浏览器 将jquery.qqFace.js表情转换成微信的字符码 手机端省市区联动 新字体引用本地运行可以获得,放到服务器上报404 C#提取html中的汉字 MVC几种找不到资源的解决方式 使用Windows服务定时去执行一个方法的三种方式
- 页面上2个按钮,当提交表单的时候调用不同的方法,但是都需要把页面上面的查询条件提交给action
- 一个表单中有编辑和删除两个按钮分别调用后台action的不同方法
- 使用MVC中的HtmlHelper对象的ActionLink方法,实现一个Javascript:void(0)效果,去调用一个JS方法
- OGNL表达式(对方法的调用,对root,context上下文对象的概念,以及测试调用方法)
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)