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. MacOS系统下简单安装以及配置MongoDB数据库(一)

    最近写了一个用node来操作MongoDB完成增.删.改.查.排序.分页功能的示例,并且已经放在了服务器上地址:http://39.105.32.180:3333. 项目一共四部分: 1.MacOS下 ...

  2. 解决Ubuntu不能全屏问题

    解决虚拟机中Ubuntu14.04系统安装VM Tools 时出现以下信息: 请确保您已登录客户机操作系统.在客户机中装载CD驱动器启动终端,使用tar解压缩安装程序,然后执行vmware-insal ...

  3. IE,表头固定

    <html>  <head>   <title>表头固定</title>    <style type="text/css"& ...

  4. 页面定制CSS代码初探(三):设置正文最小高度

    前言 没想到再次写这篇,已经过去1年半了. 现在审美也发生了改变,一开始做的样式全删了,只保留了h2的样式.原先认为界面要宽,两边留太多空很浪费,看惯了知乎和简书,觉得默认最大1000px的排版也不错 ...

  5. vue 中判断向上滚动还是向下滚动

    <script> export default { data(){ return{ i = 0 } }, mounted () { window.addEventListener('scr ...

  6. JS中通过LayUI的layer.prompt弹出文本输入层,多个按钮回调获取输入值

    JS中通过LayUI弹出文本输入层,多个按钮回调: 如图所示,输入文本后点击通过/不通过按钮回调获取输入文本值的实现: 实现JS: layer.prompt({ formType: 2, // 弹出文 ...

  7. 记录——本地minikube安装ubuntu镜像总是报 Back-off restarting failed container问题 -已解决(更新)

    1.环境介绍 使用本机系统:macX minikube镜像:安装的阿里云提供的镜像(否则总是提示访问google的api,不FQ无法成功) 虚拟机情况:使用Virtual box 的虚拟机环境 min ...

  8. Mysql ERROR 1067: Invalid default value for 字段

    问题: //今天把一个数据库的sql文件导入到另一个数据库出现以下异常: Mysql ERROR 1067: Invalid default value for 字段 //原因是因为之前导出数据里面有 ...

  9. node——文件夹创建

    //创建文件夹 var fs=require('fs'); //1.异步 fs.mkdir("./第一个目录",function(err){ if (err) { return c ...

  10. jupyter的安装

    3.6:\Lib\site-packages\pip\models\index.py # PyPI = Index('https://pypi.python.org/') # 替换成 PyPI = I ...