`

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

分享到:
评论

相关推荐

    Javascript 闭包完整解释

    ### JavaScript闭包完整解释 #### 一、闭包的基本概念 **闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...

    js闭包学习

    闭包的用途广泛,主要有以下几点: 1. **保护变量**:闭包可以用来创建私有变量,因为外部无法直接访问这些变量,避免了全局变量污染和意外修改。 2. **数据持久化**:如上述示例所示,通过闭包,局部变量可以在...

    js闭包理解

    闭包可以用于各种用途,如延迟执行(例1:为函数引用设置延时)、封装相关功能(例2:包装相关的功能)等。例如,你可以使用闭包来实现定时器,确保函数只在特定时间后执行,而不是立即执行。 在JavaScript中,`...

    js闭包的介绍

    4. **闭包的用途** - **读取内部变量**:闭包提供了一种方式,使得外部可以间接访问到内部函数的局部变量,但不能直接修改它们。 - **保持变量状态**:由于闭包的存在,函数内部的变量不会在函数执行完后立即销毁...

    什么是js闭包

    ### 什么是JS闭包 #### 一、变量的作用域与闭包的基础 在JavaScript中,理解闭包之前,首先需要掌握变量的作用域概念。变量的作用域主要分为两种:全局变量和局部变量。全局变量在整个程序范围内都可以访问,而...

    [深入理解JS闭包]帮助你快速学习js的闭包,简单高效的文档资源

    四、闭包的用途 1. 保护变量:闭包可以用来保护函数内的变量不被外部直接访问,实现数据的封装。 2. 保持状态:闭包可以使得函数内的变量在函数执行结束后仍然存在于内存中,下次调用时仍然能访问到这些变量。例如,...

    基于javascript 闭包基础分享

    闭包的用途非常广泛,以下是几个常见用例: 1. 模拟私有变量和方法:在面向对象编程中,有时需要封装某些变量和方法,使其对外不可见。在JavaScript中,利用闭包可以实现私有成员,外部无法直接访问,但可以通过...

    javascript深入理解js闭包.docx

    4. 闭包的用途 - 访问函数内部变量:闭包使得函数内部的变量可以在函数执行完毕后依然保留,例如在上述例子中,`n`的值在`f1`执行后仍然被保留,通过`nAdd`函数可以继续修改`n`的值。 - 保持状态:闭包可以用来...

    JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解

    在深入讨论JavaScript闭包之前,首先需要了解JavaScript的变量作用域。在JavaScript中,变量的作用域分为两种:全局变量和局部变量。全局变量是在函数外部定义的变量,可以在JavaScript程序的任何地方被访问。局部...

    JavaScript闭包详解1

    闭包的一个主要用途是实现数据隐私,即设计私有方法和变量。在JavaScript中,没有真正的私有成员,但可以通过闭包模拟这一行为: ```javascript function counter() { var count = 0; return { increment: ...

    JavaScript闭包(closure).pdf

    理解并掌握JavaScript闭包是成为专业前端开发者的关键一步。在实际开发中,合理利用闭包可以提高代码的复用性和可维护性,同时也能避免一些常见的编程陷阱。通过深入学习和实践,可以更好地运用闭包这一强大的工具来...

    深入解析Javascript闭包的功能及实现方法

    JavaScript中的闭包是一种强大的特性,它允许函数访问和操作其外部作用域的变量,即使在其外部函数已经执行完毕后。闭包的实现基于JavaScript的作用域链和垃圾回收机制。 1. **闭包的概念** 闭包是一个拥有自身...

    JS匿名函数、闭包

    ### JS匿名函数、闭包详解 #### 一、匿名函数概览 **匿名函数**,又称**拉姆达函数**,是一种在JavaScript中常见的函数形式,这类函数没有名称,因此不能像命名函数那样通过名称来调用。匿名函数通常作为临时使用...

    js闭包的用途详解

    我们来看看闭包的用途。事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。 1 匿名自执行函数 我们知道所有的变量,如果不加上...

    js闭包 this 。。。。。。。。

    4. **闭包的用途** - 访问和修改外部函数的局部变量,实现数据的隐藏和封装。 - 保持变量的状态,使得变量的值在函数调用之间得以保留,避免每次调用时重新初始化。 - 在某些情况下,可以用来创建私有变量和方法...

    js代码-JS闭包以及优化

    闭包的主要用途包括: 1. **数据封装**:通过闭包,我们可以创建私有变量,防止全局变量污染和意外修改。 2. **记忆功能**:闭包可以保留上一次执行的状态,常用于实现简单的缓存或计数器。 3. **模块化**:闭包...

Global site tag (gtag.js) - Google Analytics