JS闭包的详解
一、什么是闭包?
特点:
1 函数嵌套函数
2 内部函数可以引用外部的参数和变量
3 参数和变量不会被垃圾回收机制所回收
举一个简单的闭包的例子,例子中符合闭包的三个特点
function aaa(a){
var b = 5;
function bbb(){
alert(a);
alert(b);
}
}
aaa();
关于js 中的垃圾回收机制,这里说明一下。请看下面代码,当aaa函数执行完毕之后,aaa中的变量a会被js的垃圾回收机制所回收
function aaa(){
var a = 1;
}
aaa(); // 改函数执行完毕时候,函数中的变量a会被js的垃圾回收机制所回收
再举一个闭包例子
当aaa函数执行完毕之后,调用c函数仍然可以弹出1,说明了a这个变量没有被垃圾回收
function aaa(){
var a = 1;
function bbb(){
alert(a);
}
return bbb;
}
var c = aaa(); // 当aaa函数执行完毕之后,调用c函数仍然可以弹出1,说明了a这个变量没有被垃圾回收
c();
二、闭包有什么好处?应用在哪?
2.1 好处:
1 可以使一个变量常驻内存
2 避免全局变量的污染
3 私有成员变量的存在
举个例子,例子中,使用全局变量a实现每次调用aaa函数,变量a++,过多使用全局变量不容易维护(全局变量的污染)。
var a = 1;
function aaa(){
a++;
alert(a);
}
aaa(); //2
aaa(); //3
alert(a); // 这里的a是全局变量
下面,使用闭包实现这个例子:
由于a是局部变量,防止了全局变量污染
function aaa(){
var a = 1;
return function bbb(){
a++;
alert(a);
}
}
var b = aaa();
b(); //2
b(); //3
alert(a); // 由于a是局部变量,外面无法引用,程序报错
使用函数表达式的形式,改造上面例子
关于函数表达式的知识点,可以查看JS函数声明与函数表达式的区别 http://www.cnblogs.com/linhp/p/6085567.html
var aaa = (function (){
var a = 1;
return function bbb(){
a++;
alert(a);
}
})();// 这里已经执行了
aaa(); //2
aaa(); //3
私有成员变量的例子:
将表达式中的函数bbb与ccc通过json的方式返回,外部只能调用返回的json中的函数bbb和ccc,而无法访问a这个成员变量。
var aaa = (function (){
var a = 1;
function bbb(){
a++;
alert(a);
}
function ccc(){
a++;
alert(a);
}
return {b:bbb,c:ccc}
})();
aaa.b();
aaa.c();
2.2 用法:
1 模块化代码
2 在循环中,直接找到对应元素的索引
模块化代码就不举例了,上面的代码都能体现
下面举例(在循环中,直接找到对应元素的索引)
先看下面例子:
<script>
window.onload = function (){
var oLi = document.getElementsByTagName("li");
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick = function (){
alert(i);
}
}
}
</script>
<ul>
<li>111111111111</li>
<li>222222222222</li>
<li>333333333333</li>
</ul>
上面例子中,想通过给每一个li添加点击事件,点击每个li,弹出li的索引,而上面例子中,由于for循环已经结束,而onclick事件还没触发,此时i已经等于3了,所以你无论点击哪一个li都无法获取索引,弹出的值都是3
下面,通过闭包的形式,改造,获取索引
window.onload = function (){
var oLi = document.getElementsByTagName("li");
for (var i = 0; i < oLi.length; i++) {
(function(i){
oLi[i].onclick = function (){
alert(i);
}
})(i); //循环过程中,这里已经执行了。参数i永驻内存,所以当你点击li的时候,可以获取得到0,1,2
}
}
也可以改造成下面的样子
window.onload = function (){
var oLi = document.getElementsByTagName("li");
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick = (function (i){
return function(){
alert(i)
};
})(i);
}
}
三、闭包需要注意的地方?
3.1 IE下会引发内存泄露
内存泄露会导致浏览器内存占用过高,内存中的变量无法变量,必须关闭浏览器,关闭这个网页也无法清除
window.onload = function(){
var oDiv = document.getElementById("div1");
oDiv.onclick = function(){
alert(oDiv.id); // 由于内部引用了oDiv,导致oDiv无法释放
}
}
可以通过onunload事件,将onclick取消,来释放oDiv
window.onload = function(){
var oDiv = document.getElementById("div1");
oDiv.onclick = function(){
alert(oDiv.id); // 由于内部引用了oDiv,导致oDiv无法释放
}
window.onunload = function(){
oDiv.onclick = null;
}
}
或者:
window.onload = function(){
var oDiv = document.getElementById("div1");
var id = oDiv.id;
oDiv.onclick = function(){
alert(id); // 由于内部引用了oDiv,导致oDiv无法释放
}
oDiv = null;
}
JS闭包的详解的更多相关文章
- 《Node.js开发实战详解》学习笔记
<Node.js开发实战详解>学习笔记 ——持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...
- Js apply 方法 详解
Js apply方法详解 我在一开始看到JavaScript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...
- ES6,ES2105核心功能一览,js新特性详解
ES6,ES2105核心功能一览,js新特性详解 过去几年 JavaScript 发生了很大的变化.ES6(ECMAScript 6.ES2105)是 JavaScript 语言的新标准,2015 年 ...
- Js apply()使用详解
Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...
- Js apply方法详解,及其apply()方法的妙用
Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...
- Vue.js 数据绑定语法详解
Vue.js 数据绑定语法详解 一.总结 一句话总结:Vue.js 的模板是基于 DOM 实现的.这意味着所有的 Vue.js 模板都是可解析的有效的 HTML,且通过一些特殊的特性做了增强.Vue ...
- JS hashMap实例详解
链接:http://www.jb51.net/article/85111.htm JS hashMap实例详解 作者:囧侠 字体:[增加 减小] 类型:转载 时间:2016-05-26我要评论 这篇文 ...
- JS - Promise使用详解--摘抄笔记
第一部分: JS - Promise使用详解1(基本概念.使用优点) 一.promises相关概念 promises 的概念是由 CommonJS 小组的成员在 Promises/A 规范中提出来的. ...
- JS变量对象详解
JS变量对象详解 开年之后工作热情一直不是很高,这几天一直处于消极怠工状态.早上不想起床,起床了不想上班.明明放假之前工作热情还一直很高,一直心心念念的想把小程序项目怼出来,结果休假回来之后画风完全不 ...
随机推荐
- uni-app——小程序插件使用wx.createSelectorQuery()获取不到节点信息
发现小程序一个bug, 在小程序插件中使用wx.createSelectorQuery()获取不到节点信息,需要在后面加入in(this) 例如: const query = wx.createSel ...
- MySQL教程和使用手册
MySQL 教程 MySQL 教程.MySQL 安装.MySQL 管理.MySQL PHP 语法.MySQL 连接.MySQL 创建数据库.MySQL 删除数据库.MySQL 选择数据库.MySQL ...
- Redis 5.0.7 讲解,单机、集群模式搭建
Redis 5.0.7 讲解,单机.集群模式搭建 一.Redis 介绍 不管你是从事 Python.Java.Go.PHP.Ruby等等... Redis都应该是一个比较熟悉的中间件.而大部分经常写业 ...
- 使用密码登陆Amazon EC2
用的是亚马逊推荐的系统:Amazon Linux AMI 2015.09.1 (HVM) 创建instance后,会有一个pem的key使用该密钥登陆到服务器上后,默认用户名为 ec2-user 直接 ...
- Pandas DataFrame操作
DataFrame的创建 >>> import pandas as pd >>> from pandas import DataFrame #define a di ...
- git使用记录一:配置账户信息
配置的级别 git config --gloabal 针对当前用户下所有的项目 设置 git config --local 针对当前工作区的项目来进行设置 git config --system 针对 ...
- log4j日志记录到数据库
log4j API提供 org.apache.log4j.jdbc.JDBCAppender 对象,它能够将日志信息在指定的数据库. JDBCAppender 配置: Property 描述 buff ...
- php &引用符的注意情况
- Python中反射的简单应用
● 共两个文件:userInfo,reflex.py alex|123456|Manager hezewei|666|Student taibai|2222|Teachar userInfo #!/u ...
- python基础【第五篇】
python第三节 1.整型及布尔值 1.1 进制转换 十进制 ----二进制 二进制 ----十进制 8421方法与普通计算 python中十进制转二进制示例:bin(51)>>> ...