闭包
2016-02-21 21:01
357 查看
//声明一个闭包 function f1() { var week="Sunday"; function f2() { console.log('星期:'+week); } return f2; } var ff=f1(); //以上代码已经形成一个闭包,其是一个函数,ff就是这个函数 //f1执行后返回f2函数,函数对象对ff进行赋值(引用赋值) //调用闭包函数ff,使其发生执行 //ff和f2是同一个function的两个不同名字,f2是局部变量,ff是全局变量 //因此,该function可以在内部、外部环境同时访问 //无论是内部还是外部环境,只要function执行,就具体上下级环境没有直接关系 //内部的week永远都是我们自己AO活动对象的属性 //因此,只要该function能够访问到,就无视内部变量的来源,其就是函数AO活动对象的属性,是固化好的。 ff();//Sunday
//闭包使用规则: //同一个闭包机制可以创建多个闭包函数出来,它们彼此没有联系,都是独立的,并且每个闭包可以保存自己个性化的信息。 function f1(num){ //外部变量:变量、参数、函数 //var num=100;//num就是f1函数的形参,也是其局部变量 function f2(){//f2可以访问f1中的变量num console.log("数字:"+num);//100 } return f2; } /* var fa=f1(100); fa();//100 var fb=f1(110); fb();//110*/ //闭包机制每调用一次,就生成一个闭包函数 var fa=f1(100); var fb=f1(110); var fc=f1(120); fa();//100 fb();//110 fc();//120
function f1(num){ //外部变量:变量、参数、函数 var num=200; function f2(){ console.log("数字:"+num++); //num++是先把结果返回再加 //++num是先相加再返回结果 } return f2; } //生成闭包 var fa=f1(); fa();//200 fa();//201 var fb=f1();//fa、fb两个闭包之间没有联系 fb();//200 fb();//201
闭包事件操作
<h2>闭包事件操作</h2> <ul> <li>奔驰</li> <li>宝马</li> <li>奥迪</li> </ul>
<pre name="code" class="javascript">//给li设置mouseover和mouseout事件,鼠标滑过高亮显示当前行 window.onload=function(){ var lis=document.getElementsByTagName("li"); for(var i=0;i<lis.length;i++) { lis[i].onmouseover=over(i);//闭包 //lis[0].onmouseover=function(){lis[i].style.background="pink";}; //lis[1].onmouseover=function(){lis[i].style.background="pink";}; //lis[2].onmouseover=function(){lis[i].style.background="pink";}; //此处只是声明但是并没有执行,当执行的时候i已经定格为3 lis[i].onmouseout=out(i);//闭包 } function over(n){ function f2(){ lis .style.background="pink"; } return f2; } function out(n){ function f2(){ lis .style.background=""; } return f2; } }; </script>
//闭包案例--创建数组 var arr=new Array(); for(var i=0;i<4;i++){ arr[i]=function(){ console.log(i); } //alert(arr[i]);//弹出function(){console.log(i)};说明下面的声明解释是正确的 /* 以上代码相当于声明了一下代码: for(var i=0;i<4;i++){ arr[0]=function(){console.log(i);} arr[1]=function(){console.log(i);} arr[2]=function(){console.log(i);} arr[3]=function(){console.log(i);}*/ //当真正执行的时候i已经变为4 } arr[2]();//4 arr[1]();//4 arr[0]();//4 arr[3]();//4 //以上4个数组元素函数调用没有输出理想的信息,而是输出4 //变量i是var声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值
var arr=new Array(); for(var i=0;i<4;i++){ //arr[i]=闭包; arr[i]=f1(i);//通过调用f1()闭包机制,生成多个独立函数,并且每个函数的i变量都是不同值 /* arr[0]=f1(0)=function f2(){console.log(0);}; arr[1]=f1(1)=function f2(){console.log(1);}; arr[2]=f1(2)=function f2(){console.log(2);}; arr[3]=f1(3)=function f2(){console.log(3);}; */ } function f1(n){ function f2(){ console.log(n);//可以访问外函数f1的形参n } return f2; } arr[2]();//2 arr[1]();//1 arr[0]();//0 arr[3]();//3
Javascript垃圾回收方法
标记清除(mark and sweep)
这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
引用计数(reference counting)
在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。在IE中虽然
JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的,也就是说只要涉及
BOM及DOM就会出现循环引用问题。
相关文章推荐
- iOS关于CAShapeLayer与UIBezierPath的知识内容
- 聚电解质纳米凝胶的标度理论
- 深入.NET框架
- [爬虫系列(三)]用多线程爬取百度贴吧默认表情
- XML约束文件---DTD文件
- android xliff:g标签
- 从几个版本的memcpy的测速过程学习一点底层的东西
- offsetHeight,offsetWidth.....那些易混淆的几个几个知识点
- 已知两条直线上各两点坐标,求两条直线交点坐标
- 转行自学android,Day2-真正的东西
- iptables之显示扩展基础应用(二)
- 当公司裁员的时候
- 自定义单元格的4种方式
- eclipse导入myeclipse项目
- 【caffe学习笔记二】——运行例子,caffe跑起来
- CSS定位与浮动
- iOS 学习第十六天 OC语言 autorelease基本使用
- Educational Codeforces Round 8 F. Bear and Fair Set 最大流
- 2016/02/21 codes
- 飞机调度(Now or later,LA 3211)