一、什么是闭包?

特点:

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闭包的详解的更多相关文章

  1. 《Node.js开发实战详解》学习笔记

    <Node.js开发实战详解>学习笔记 ——持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...

  2. Js apply 方法 详解

    Js apply方法详解 我在一开始看到JavaScript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...

  3. ES6,ES2105核心功能一览,js新特性详解

    ES6,ES2105核心功能一览,js新特性详解 过去几年 JavaScript 发生了很大的变化.ES6(ECMAScript 6.ES2105)是 JavaScript 语言的新标准,2015 年 ...

  4. Js apply()使用详解

    Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...

  5. Js apply方法详解,及其apply()方法的妙用

    Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...

  6. Vue.js 数据绑定语法详解

    Vue.js 数据绑定语法详解 一.总结 一句话总结:Vue.js 的模板是基于 DOM 实现的.这意味着所有的 Vue.js 模板都是可解析的有效的 HTML,且通过一些特殊的特性做了增强.Vue ...

  7. JS hashMap实例详解

    链接:http://www.jb51.net/article/85111.htm JS hashMap实例详解 作者:囧侠 字体:[增加 减小] 类型:转载 时间:2016-05-26我要评论 这篇文 ...

  8. JS - Promise使用详解--摘抄笔记

    第一部分: JS - Promise使用详解1(基本概念.使用优点) 一.promises相关概念 promises 的概念是由 CommonJS 小组的成员在 Promises/A 规范中提出来的. ...

  9. JS变量对象详解

    JS变量对象详解 开年之后工作热情一直不是很高,这几天一直处于消极怠工状态.早上不想起床,起床了不想上班.明明放假之前工作热情还一直很高,一直心心念念的想把小程序项目怼出来,结果休假回来之后画风完全不 ...

随机推荐

  1. Toast 使用方法大全

    原文地址:http://daikainan.iteye.com/blog/1405575 Toast 是一个 View 视图,快速的为用户显示少量的信息. Toast 在应用程序上浮动显示信息给用户, ...

  2. 《ArcGIS Runtime SDK for .Net开发笔记》--介绍与环境搭建

    一. ArcGIS Runtime SDK for .NET介绍 ArcGIS Runtime SDK for .net是一款针对windows平台的开发包.能够在开发出在windows phone, ...

  3. appium自动化测试- 元素操作

    本文转自:https://www.cnblogs.com/sinder2018/articles/9699801.html 一.滑动屏幕 1.appium - 滑动屏幕 滑动接口: swipe(起始X ...

  4. bp网络全解读

    https://blog.csdn.net/weixin_40432828/article/details/82192709

  5. C#中Json转换主要使用的几种方法!

    这篇主要介绍2.4.第三种方法使用的比较局限,所以我没有深入学习. 第二种方法 我使用比较多的方式,这个方法是.NET内置的,使用起来比较方便 A.利用serializer获取json的泛型对象 利用 ...

  6. ES6数组中删除指定元素

    知识点: ES6从数组中删除指定元素 findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引.否则返回-1. arr.splice(arr.findIndex(item => ...

  7. FPGA前仿真后仿真

    前仿真 后仿真 时序(综合后)仿真 时序仿真将时延考虑进去,包括综合后产生的(与.或.非)门时延,还有布局布线产生的时延. 综合(Synthesize),就是将HDL语言设计输入翻译成由与.或.非门和 ...

  8. openstack部署安装

    OpenStack实战 准备环境 controller 10.0.0.11 compute1 10.0.0.31 常用服务端口 mariadb:3306 memcached:11211 消息队列:56 ...

  9. Scrapy框架: settings.py设置

    # -*- coding: utf-8 -*- # Scrapy settings for maitian project # # For simplicity, this file contains ...

  10. element ui step组件在另一侧加时间轴显示

    这是我开发的时候遇到的一个问题:项目需要在步骤条(竖直方向)的另一侧加时间显示,但是我在element ui 的step组件中一直没找着设置方法,所以就自己想了个办法加进来,效果如下: 代码如下,先上 ...