我们来看看闭包的用途。事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。
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概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...
闭包的用途广泛,主要有以下几点: 1. **保护变量**:闭包可以用来创建私有变量,因为外部无法直接访问这些变量,避免了全局变量污染和意外修改。 2. **数据持久化**:如上述示例所示,通过闭包,局部变量可以在...
闭包可以用于各种用途,如延迟执行(例1:为函数引用设置延时)、封装相关功能(例2:包装相关的功能)等。例如,你可以使用闭包来实现定时器,确保函数只在特定时间后执行,而不是立即执行。 在JavaScript中,`...
4. **闭包的用途** - **读取内部变量**:闭包提供了一种方式,使得外部可以间接访问到内部函数的局部变量,但不能直接修改它们。 - **保持变量状态**:由于闭包的存在,函数内部的变量不会在函数执行完后立即销毁...
### 什么是JS闭包 #### 一、变量的作用域与闭包的基础 在JavaScript中,理解闭包之前,首先需要掌握变量的作用域概念。变量的作用域主要分为两种:全局变量和局部变量。全局变量在整个程序范围内都可以访问,而...
四、闭包的用途 1. 保护变量:闭包可以用来保护函数内的变量不被外部直接访问,实现数据的封装。 2. 保持状态:闭包可以使得函数内的变量在函数执行结束后仍然存在于内存中,下次调用时仍然能访问到这些变量。例如,...
闭包的用途非常广泛,以下是几个常见用例: 1. 模拟私有变量和方法:在面向对象编程中,有时需要封装某些变量和方法,使其对外不可见。在JavaScript中,利用闭包可以实现私有成员,外部无法直接访问,但可以通过...
4. 闭包的用途 - 访问函数内部变量:闭包使得函数内部的变量可以在函数执行完毕后依然保留,例如在上述例子中,`n`的值在`f1`执行后仍然被保留,通过`nAdd`函数可以继续修改`n`的值。 - 保持状态:闭包可以用来...
在深入讨论JavaScript闭包之前,首先需要了解JavaScript的变量作用域。在JavaScript中,变量的作用域分为两种:全局变量和局部变量。全局变量是在函数外部定义的变量,可以在JavaScript程序的任何地方被访问。局部...
闭包的一个主要用途是实现数据隐私,即设计私有方法和变量。在JavaScript中,没有真正的私有成员,但可以通过闭包模拟这一行为: ```javascript function counter() { var count = 0; return { increment: ...
理解并掌握JavaScript闭包是成为专业前端开发者的关键一步。在实际开发中,合理利用闭包可以提高代码的复用性和可维护性,同时也能避免一些常见的编程陷阱。通过深入学习和实践,可以更好地运用闭包这一强大的工具来...
JavaScript中的闭包是一种强大的特性,它允许函数访问和操作其外部作用域的变量,即使在其外部函数已经执行完毕后。闭包的实现基于JavaScript的作用域链和垃圾回收机制。 1. **闭包的概念** 闭包是一个拥有自身...
### JS匿名函数、闭包详解 #### 一、匿名函数概览 **匿名函数**,又称**拉姆达函数**,是一种在JavaScript中常见的函数形式,这类函数没有名称,因此不能像命名函数那样通过名称来调用。匿名函数通常作为临时使用...
### 学习JavaScript闭包详解 #### 一、引言 闭包是JavaScript语言中一个重要的概念,也是理解和掌握高级编程技巧的关键之一。本文将基于阮一峰的文章《学习JavaScript闭包》进行深入探讨,旨在帮助读者理解闭包的...
我们来看看闭包的用途。事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。 1 匿名自执行函数 我们知道所有的变量,如果不加上...
4. **闭包的用途** - 访问和修改外部函数的局部变量,实现数据的隐藏和封装。 - 保持变量的状态,使得变量的值在函数调用之间得以保留,避免每次调用时重新初始化。 - 在某些情况下,可以用来创建私有变量和方法...
闭包的主要用途包括: 1. **数据封装**:通过闭包,我们可以创建私有变量,防止全局变量污染和意外修改。 2. **记忆功能**:闭包可以保留上一次执行的状态,常用于实现简单的缓存或计数器。 3. **模块化**:闭包...