js闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中

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

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闭包的作用了,非常简单易懂吧,希望对小伙伴们有所帮助

js闭包的用途详解的更多相关文章

  1. js 闭包的用法详解

    一.闭包 实现可重用的局部变量,且保护其不受污染的机制. 外层函数包裹受保护的变量和内层函数. 内层函数专门负责操作外层函数的局部变量. 将内层函数返回到外层函数外部,反复调用. 二.作用域 子函数会 ...

  2. js调试工具Console命令详解

    这篇文章主要介绍了js调试工具Console命令详解,需要的朋友可以参考下   一.显示信息的命令 复制代码 代码如下: < !DOCTYPE html> < html> &l ...

  3. Js闭包的用途

    本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...

  4. JQ的offset().top与js的offsetTop区别详解

    一.前言 最近在做一个图片懒加载的插件,就纵轴(Y轴)而言,我需要时时获取图片的上偏移量,好判断是否已进入视图区域,而我所理解的是offsetTop应该是跟offset().top一样的,然后陷入了因 ...

  5. JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离

     壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...

  6. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  7. JS中this关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 阅读此文章,还需要心平气和的阅读完,相信一定会有所收获,我也会不定期的发布,分享一些文章,共同学习 首先,必须搞清楚在JS里面,函数 ...

  8. JS 中 this 关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 首先,必须搞清楚在JS里面,函数的几种调用方式: 普通函数调用 作为方法来调用 作为构造函数来调用 使用apply/call方法来调 ...

  9. Js apply() call()使用详解

    Js apply方法详解我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里 ...

随机推荐

  1. ndis6 how to drop packets

    In ndis6 how to drop packets? in FilterSendNetBufferLists: FILTER_RELEASE_LOCK(&pFilter->Lock ...

  2. RedHat/CentOS(Linux)双网卡bond(mode=6)

    1. 将/etc/sysconfig/network-scripts/ifcfg-ens1f0和ifcfg-ens1f1文件备份到root目录下2. 修改/etc/sysconfig/network- ...

  3. hook的本质就是在本原可执行文件中加东西

    hook的本质就是在本原可执行文件中加东西. 本质就是添加东西:

  4. 什么是2.5D与3D编辑模式

    ZBrush®其实就是一个带有三维特性的二维软件,它不仅具有绘制二维图像的功能,而且也具有对三维物体进行编辑的功能,就是所谓的2.5D(Pixol技术). 学习ZBrush之前有必要了解一下2.5D的 ...

  5. 怎样验证layer.prompt输入的值为数值型???

    JS中使用isNaN()判断layer.prompt输入的值为数值型,代码如下: layer.prompt({ title: '设置比值', }, function(value, index, ele ...

  6. C#追加、拷贝、删除、移动文件、创建目录、递归删除文件夹及文件

    C#追加文件 StreamWriter sw = File.AppendText(Server.MapPath(".")+"\\myText.txt"); sw ...

  7. js实现鼠标吸附线条效果

    如图,箭头→为鼠标位置,鼠标会带有吸附着一些线条的效果,具体效果可在我的博客查看,当然,这也是可很受欢迎很常见的效果了=3= <script> !function(){ function ...

  8. SQL SERVER-集合操作

    内连接      INNER JOIN(等值连接):只显示两个表中联结字段相等的行.这个和用select查询多表是一样的效果,所以很少用到:外连接:LEFT JOIN :以左表为基础,显示左表中的所有 ...

  9. HDU 4089

    很容易列出方程 设dp[i][j]为排在第i位置,总共有j个人排队到达目标状态的概率 i=1 dp[i][j]=p4+p1*dp[i][j]+p2*dp[j][j] 2<=i<=k dp[ ...

  10. 阿里云server部署架构

    近期要上马一个项目,客户要求所有部署到阿里云的server,做了一个阿里云的部署方案. 上图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc21hbGx ...