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 相关文章推荐
onsubmit阻止form表单提交与onclick的相关操作
Sep 03 Javascript
让AJAX不依赖后端接口实现方案
Dec 03 Javascript
jquery移除、绑定、触发元素事件使用示例详解
Apr 10 Javascript
jQuery实现渐变下拉菜单的简单方法
Mar 11 Javascript
jquery网页日历显示控件calendar3.1使用详解
Nov 24 Javascript
JavaScript微信定位功能实现方法
Nov 29 Javascript
javascript实现日期三级联动下拉框选择菜单
Dec 03 Javascript
基于jstree使用AJAX请求获取数据形成树
Aug 29 Javascript
vue2.0在没有dev-server.js下的本地数据配置方法
Feb 23 Javascript
通过GASP让vue实现动态效果实例代码详解
Nov 24 Javascript
Vue 中获取当前时间并实时刷新的实现代码
May 12 Javascript
Javascript数组及类数组相关原理详解
Oct 29 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
PHP版网站缓存加快打开速度的方法分享
2012/06/03 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
2019/03/12 PHP
PHP网站常见安全漏洞,及相应防范措施总结
2021/03/01 PHP
利用javascript中的call实现继承
2007/01/22 Javascript
JavaScript 一行代码,轻松搞定浮动快捷留言-V2升级版
2010/04/02 Javascript
javascript之Partial Application学习
2013/01/10 Javascript
使用js实现一个可编辑的select下拉列表
2014/02/20 Javascript
介绍JavaScript的一个微型模版
2015/06/24 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
jQuery实现网页顶部固定导航效果代码
2015/12/24 Javascript
easyUI实现类似搜索框关键词自动提示功能示例代码
2016/12/27 Javascript
JavaScript数据类型和变量_动力节点Java学院整理
2017/06/26 Javascript
微信JSAPI Ticket接口签名详解
2020/06/28 Javascript
vue项目总结之文件夹结构配置详解
2017/12/13 Javascript
[02:56]DOTA2上海特锦赛小组赛解说FreeAgain采访花絮
2016/02/27 DOTA
Python多线程编程简单介绍
2015/04/13 Python
python 用正则表达式筛选文本信息的实例
2018/06/05 Python
python实现验证码识别功能
2018/06/07 Python
python接口自动化(十六)--参数关联接口后传(详解)
2019/04/16 Python
Python3.7安装keras和TensorFlow的教程图解
2020/06/18 Python
Python vtk读取并显示dicom文件示例
2020/01/13 Python
解决python执行较大excel文件openpyxl慢问题
2020/05/15 Python
CSS3实现10种Loading效果
2016/07/11 HTML / CSS
HTML5 Canvas的性能提高技巧经验分享
2013/07/02 HTML / CSS
Veronica Beard官网:在酷、经典和别致之间找到了平衡
2018/01/11 全球购物
俄罗斯在线手表和珠宝商店:AllTime
2019/09/28 全球购物
《路旁的橡树》教学反思
2014/04/07 职场文书
签约仪式策划方案
2014/06/02 职场文书
2014年机关党委工作总结
2014/12/11 职场文书
2015年度村委会工作总结
2015/04/29 职场文书
公司庆典主持词
2015/07/04 职场文书
Nginx解决403 forbidden的完整步骤
2021/04/01 Servers
如何给HttpServletRequest增加消息头
2021/06/30 Java/Android
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python
win10更新失败无限重启解决方法
2022/04/19 数码科技
在MySQL中你成功的避开了所有索引
2022/04/20 MySQL