JavaScript闭包研究
林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka
摘要:本文主要讲了JavaScript闭包的原理、特点并用一些实例做了证明
一、闭包的概念与好处
1.1、什么是闭包?
闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
闭包的特点:
1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
闭包:是指有权访问另外一个函数作用域中的变量的函数。创建闭包的常见方式就是在一个函数内部创建另外一个函数
1.2、javascript的垃圾回收原理
1.在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
2.如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。
1.3、使用闭包的好处
那么使用闭包有什么好处呢?使用闭包的好处是:
1.希望一个变量长期驻扎在内存中
2.避免全局变量的污染
3.私有成员的存在
二、实例讲解
内部函数
让我们从一些基础的知识谈起,首先了解一下内部函数。内部函数就是定义在另一个函数中的函数。例如:
function outerFn () {functioninnerFn () {}
}
innerFn就是一个被包在outerFn作用域中的内部函数。这意味着,在outerFn内部调用innerFn是有效的,而在outerFn外部调用innerFn则是无效的。
当function里嵌套function时,内部的function可以访问外部function里的变量。
如下:
<!DOCTYPE html>
<meta charset="utf-8" />
<html>
<head>
</head>
<body><button οnclick="fun()">请点击这里</button><script>function fun(){outfun(1);}function outfun(x) { var tmp = 1; function infun(y) { alert(x + y + (++tmp)); } infun(10); } </script>
</body>
</html>
输出结果;
不管执行多少次,都会alert 13,因为infun能访问outfun的参数x,也能访问outfun的变量tmp。但,这还不是闭包。当你return的是内部function时,就是一个闭包。内部function会close-over外部function的变量直到内部function结束。
将函数更改成如下就是闭包了:
<!DOCTYPE html>
<meta charset="utf-8" />
<html>
<head>
</head>
<body><button οnclick="fun()">请点击这里</button><script>var test = outfun(1);function fun(){ test(10);}function outfun(x) { var tmp = 1; return function infun(y) { alert(x + y + (++tmp)); } //这样才是闭包} </script>
</body>
</html>
这里每次点击后结果都会加1
第一次点:
第二次点:
当然, 我们也可以使用全局变量来调用闭包
再来看一个例子
function f1(){var n=999;nAdd=function(){n+=1}//所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去function f2(){alert(n);}return f2;}var result=f1();result(); // 999nAdd();result(); // 1000
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd 的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
JavaScript中所有的function都是一个闭包。不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”。看下面这段代码:
function a() {
var i = 0;
function b() { alert(++i); }
return b;
}
var c = a();
c();
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
看完了上面,闭包其实在json中也可以来使用,这种方法在很多框架中还经常见到,最基础如下:
<script>
var aaa = (function(){var a = 1;function bbb(){a++;alert(a);}function ccc(){a++;alert(a);}return {b:bbb, //json结构c:ccc}
})();
aaa.b(); //2
aaa.c() //3
</script>
这里使用了json,返回是一个json
我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
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("input");
这样我们在第二次调用的时候,就会从缓存中读取到该对象,如果上面的例子看不懂,那就看下面的吧
var db = (function() {
// 创建一个隐藏的object, 这个object持有一些数据
// 从外部是不能访问这个object的
var data = {};
// 创建一个函数, 这个函数提供一些访问data的数据的方法
return function(key, val) {if (val === undefined) { return data[key] } // getelse { return data[key] = val } // set}
// 我们可以调用这个匿名方法
// 返回这个内部函数,它是一个闭包
})();db('x'); // 返回 undefined
db('x', 1); // 设置data['x']为1
db('x'); // 返回 1
// 我们不可能访问data这个object本身
// 但是我们可以设置它的成员
三、使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便
改变父函数内部变量的值。
JavaScript闭包研究相关推荐
- JavaScript闭包如何工作?
您将如何向了解其闭包概念(例如函数,变量等)的人解释JavaScript闭包,但却不了解闭包本身? 我已经在Wikipedia上看到了Scheme示例 ,但是不幸的是它没有帮助. #1楼 我知道已经有 ...
- JavaScript闭包的底层运行机制
转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...
- javascript 闭包_了解JavaScript闭包:实用方法
javascript 闭包 Learning a new language involves a series of steps, whereas its mastery is a product o ...
- Javascript闭包和闭包的几种写法及用途
好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途. 一.什么 ...
- JavaScript学习总结(十六)——Javascript闭包(Closure)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.很早就接触过闭包这个概念了,但是一直糊里糊涂的,没有能够弄明白JavaScript的闭包到底是什 ...
- 全面理解Javascript闭包和闭包的几种写法及用途【转】
一.什么是闭包和闭包的几种写法和用法 1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. ...
- 全面理解Javascript闭包和闭包的几种写法及用途
一.什么是闭包和闭包的几种写法和用法 1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. ...
- 让你分分钟理解 JavaScript 闭包
原文:https://www.cnblogs.com/onepixel/p/5062456.html 让你分分钟理解 JavaScript 闭包 闭包,是 Javascript 比较重要的一个概念,对 ...
- 全面理解Javascript闭包和闭包的几种写法及用途--转载自https://www.cnblogs.com/yunfeifei/p/4019504.html...
全面理解Javascript闭包和闭包的几种写法及用途 好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一 ...
最新文章
- document.getElementById vs jQuery $()
- 算法与数据结构(面向对象思想)
- 结对开发Ⅴ——循环一维数组求和最大的子数组
- 九章算法强化班 - 课程大纲
- matlab变压器损耗仿真,基于Matlab的变压器运行特性仿真专题报告.docx
- 概要设计说明书_没有什么比牙签更好的设计了
- html5新加入的内容,10个html5增加的重要新特性和内容
- oracle学习笔记(十三) 查询练习(三) 子查询查询
- 阿里开发规范_字字珠玑,高级技术专家带你了解阿里的开发流程规范
- 牛掰!某厂风控大佬整理的一套黑客学习思维导图及教程!
- Windows socket测试工具
- css基础--border属性
- JAVA8实战 -- Lamdba表达式
- Q3营收利润双降,新作将成Take-Two逆势大爆发的动力?
- ubuntu14.04 64位安装H3C iNode客户端
- 4天4夜渡劫成功,解决10月1项目上线遇到的一个Mysql大坑,导致项目无法正常访问
- HTML5+CSS3小实例:后台管理系统的侧边导航栏
- 自定义类加载器加载冲突类(一)-ClassLoader
- Mac扫描局域网内连接设备IP及MAC地址并查看对应IP开放端口
- Java中类型zhaun‘huan
热门文章
- d3.js环形统计图代码
- 各纬度气候分布图_气候气压带图_世界气候气压带风带分布图要图(需要表识纬度)-4d影院专题信息栏目...
- UVA 12235 Help Bubu
- 国产电脑支持Linux吗,天玥计算机(电脑)支持UOS、银河麒麟、Deepin等国产操作系统...
- html本地化软件,如何为本地化做准备 (HTML)
- 计算机与昆虫关系的论文,浅谈昆虫与人类的关系.doc
- 无线网络CSMA/CA原理分析以及相关技术的介绍和分析
- 数据可视化设计师必备的图表规范指南
- Win10+YOLOv5运行记录
- 20175208 张家华 MyCP