闭包
来源:互联网 发布:怎样制做淘宝原图 编辑:程序博客网 时间:2024/06/15 18:07
闭包是什么
理解是,闭包就是能够读取其他函数内部变量的函数。
本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
function f1(){
n=999;
functionf2(){
alert(n);
}
returnf2;
}
varresult=f1();
result(); //999
f2函数,就是闭包
var name = "TheWindow";
var object = {
name : "MyObject",
getNameFunc :function(){
returnfunction(){
returnthis.name;
};
}
};
alert(object.getNameFunc()()); //TheWindow
于是当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
闭包的作用
闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。
注意:1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便
闭包的应用 此部分摘自 作者:_Yfling 链接:http://www.jianshu.com/p/05de7c1ef080 來源:简书
1 匿名自执行函数
我们知道所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处,
比如:别的函数可能误用这些变量;造成全局对象过于庞大,影响访问速度(因为变量的取值是需要从原型链上遍历的)。
除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一次,其内部变量无需维护,
比如UI的初始化,那么我们可以使用闭包:
var datamodel = { table : [], tree : {} }; (function(dm){ for(var i = 0; i < dm.table.rows; i++){ var row = dm.table.rows[i]; for(var j = 0; j < row.cells; i++){ drawCell(i, j); } } //build dm.tree })(datamodel);
我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,
因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。
2缓存
再来看一个例子,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,
然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,
从而函数内部的值可以得以保留。
var CachedSearchBox = (function(){ var cache = {}, count = []; return { attachSearchBox : function(dsid){ if(dsid in cache){//如果结果在缓存中 return cache[dsid];//直接返回缓存中的对象 } var fsb = new uikit.webctrl.SearchBox(dsid);//新建 cache[dsid] = fsb;//更新缓存 if(count.length > 100){//保正缓存的大小<=100 delete cache[count.shift()]; } return fsb; }, clearSearchBox : function(dsid){ if(dsid in cache){ cache[dsid].clearSelection(); } } }; })(); CachedSearchBox.attachSearchBox("input1");
这样,当我们第二次调用CachedSearchBox.attachSerachBox(“input1”)的时候,
我们就可以从缓存中取道该对象,而不用再去创建一个新的searchbox对象。
3 实现封装
可以先来看一个关于封装的例子,在person之外的地方无法访问其内部的变量,而通过提供闭包的形式来访问:
var person = function(){ //变量作用域为函数内部,外部无法访问 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//直接访问,结果为undefined print(person.getName()); person.setName("abruzzi"); print(person.getName()); 得到结果如下: undefined default abruzzi
4 实现面向对象中的对象
传统的对象语言都提供类的模板机制,
这样不同的对象(类的实例)拥有独立的成员及状态,互不干涉。虽然JavaScript中没有类这样的机制,但是通过使用闭包,
我们可以模拟出这样的机制。还是以上边的例子来讲:
function Person(){ var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }; var john = Person(); print(john.getName()); john.setName("john"); print(john.getName()); var jack = Person(); print(jack.getName()); jack.setName("jack"); print(jack.getName()); 运行结果如下: default john default jack
由此代码可知,john和jack都可以称为是Person这个类的实例,因为这两个实例对name这个成员的访问是独立的,互不影响的。
实现一个暴露内部变量,而且外部可以访问修改的函数
(get和set,闭包实现)
var person = function(){ //变量作用域为函数内部,外部无法访问 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//直接访问,结果为undefined print(person.getName()); person.setName("abruzzi"); print(person.getName()); 得到结果如下: undefined default abruzzi
从几个li中取下标的闭包代码
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li></ul>var li=document.getElementsByTagName("li");for(var i=0;i<li.length;i++) { (function(x) { li[x].onclick=function(){alert(x);} })(i);}
实现一个闭包的例子(实现了一个定时函数传值的)
闭包:for(var i = 0; i < 10; i++ ){ (function(x){ setTimeout(function(){ console.log(x) },x*1000) })(i)}或者用全局变量实现
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 闭包
- 暑期学习 RNN 笔记
- % invalid END header (bad central directory offset) 问题解决
- 使用增强学习AI玩赛车游戏(Gym-TORCS)
- CCF 工资计算(Java)
- 实验吧-程序逻辑问题writeup
- 闭包
- Python 学习笔记(自用)(有C++基础)(连载)
- 游戏挂机小项目 每天100¥
- openstack学习
- Ajax实现分页二
- 数据库分区分表
- 开贴宣言
- 安装64位oracle用PLSQL Developer连接报错问题
- 公众号“今日作文素材”文章列表 (20170826-20170901)