js闭包的用途详解


Posted in Javascript onNovember 09, 2014

我们来看看闭包的用途。事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。

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这个成员的访问是独立的,互不影响的。

以上便是js闭包的作用了,非常简单易懂吧,希望对小伙伴们有所帮助

Javascript 相关文章推荐
Jquery Validation插件防止重复提交表单的解决方法
Mar 05 Javascript
JS高级拖动技术 setCapture,releaseCapture
Jul 31 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
Jan 10 Javascript
JavaScript数值转换的三种方式总结
Jul 31 Javascript
整理Javascript函数学习笔记
Dec 01 Javascript
JavaScript数值千分位格式化的两种简单实现方法
Aug 01 Javascript
Angular.js中$apply()和$digest()的深入理解
Oct 13 Javascript
基于jQuery实现滚动刷新效果
Jan 09 Javascript
Angular.JS中的this指向详解
May 17 Javascript
javascript用rem来做响应式开发
Jan 13 Javascript
微信小程序实现左右列表联动
May 19 Javascript
JavaScript实现表单验证功能
Dec 09 Javascript
js闭包实例汇总
Nov 09 #Javascript
浅谈JS闭包中的循环绑定处理程序
Nov 09 #Javascript
jQuery函数map()和each()介绍及异同点分析
Nov 08 #Javascript
js跨域问题浅析及解决方法优缺点对比
Nov 08 #Javascript
js 操作符汇总
Nov 08 #Javascript
jquery的总体架构分析及实现示例详解
Nov 08 #Javascript
jquery常用方法及使用示例汇总
Nov 08 #Javascript
You might like
2020年4月放送决定!第2期TV动画《邪神酱飞踢》视觉图&主题曲情报公开!
2020/03/06 日漫
php 对输入信息的进行安全过滤的函数代码
2012/06/29 PHP
基于PHP静态类的原罪详解
2013/05/06 PHP
基于PHP创建Cookie数组的详解
2013/07/03 PHP
php中将数组转成字符串并保存到数据库中的函数代码
2013/09/29 PHP
PHP搭建大文件切割分块上传功能示例
2017/01/04 PHP
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
2017/11/17 PHP
用函数式编程技术编写优美的 JavaScript_ibm
2008/05/16 Javascript
了解一点js的Eval函数
2012/07/26 Javascript
javascript验证香港身份证的格式或真实性
2017/02/07 Javascript
js中new一个对象的过程
2017/02/20 Javascript
基于vue2的table分页组件实现方法
2017/03/20 Javascript
详解Vue打包优化之code spliting
2018/04/09 Javascript
[14:36]2014 DOTA2国际邀请赛中国区预选赛5.21 Orenda VS NE
2014/05/22 DOTA
python基础教程之python消息摘要算法使用示例
2014/02/10 Python
python实现从web抓取文档的方法
2014/09/26 Python
python开发之str.format()用法实例分析
2016/02/22 Python
简述Python2与Python3的不同点
2018/01/21 Python
详解Django之admin组件的使用和源码剖析
2018/05/04 Python
python 读取文件并替换字段的实例
2018/07/12 Python
Linux上使用Python统计每天的键盘输入次数
2019/04/17 Python
基于多进程中APScheduler重复运行的解决方法
2019/07/22 Python
python suds访问webservice服务实现
2020/06/26 Python
6号汽车旅馆预订:Motel 6
2018/02/11 全球购物
英国在线药房和在线药剂师:Chemist 4 U
2020/01/05 全球购物
物理专业大学生职业生涯规划书
2014/02/07 职场文书
幼儿园老师寄语
2014/04/03 职场文书
《赶海》教学反思
2014/04/20 职场文书
政治思想表现评语
2014/05/04 职场文书
地球一小时宣传标语
2014/06/24 职场文书
个人先进事迹材料范文
2014/12/29 职场文书
2015年中秋放假通知范文
2015/08/18 职场文书
团支部组织委员竞选稿
2015/11/21 职场文书
导游词之西湖雷峰塔
2019/09/18 职场文书
解决numpy和torch数据类型转化的问题
2021/05/23 Python
JPA 通过Specification如何实现复杂查询
2021/11/23 Java/Android