之前有整理过一版关于闭包的概念,但感觉思路不是很清晰,是临时想起一些例子来讲的,今天再次来讲一下闭包。

闭包:

函数嵌套函数,内部函数可以引用外部函数的参数和变量

function aaa(a){
var b=5;
function bbb(){
alert(a);
alert(b);
}
}

在上面的例子当中,bbb函数是可以访问到aaa函数中的a和b的,同时,JS中的垃圾回收机制也不会回收a,b。

function aaa(){
var a =5;
function bbb(){
alert(a);
}
return bbb;
} var c = aaa();
c();

可以看到此时调用c()是可以弹出5的,即a在调用aaa()之后是没有被回收的。即常驻内存。

闭包的好处:

1 希望一个变量可以长期驻扎在内存,之前已经说明。

2 避免全局变量污染

var a=1;
function aaa(){
a++;
alert(a);
}
aaa();    //2
aaa();    //3

此时函数aaa访问的是全局变量a,那么就很容易被其他函数或程序修改。那么可以使用一下代码来避免这个问题

function aaa(){
var a=5;
return function(){
a++;
alert(a);
}
}
var b=aaa();
b();    //6
b();    //7
alert(a)  //error

以上的例子中可以看出已经把a放进函数里作为一个局部变量被引用,a也会常驻内存,不会被垃圾回收清理。

还可以将其改写成函数声明表达式:将function用括号包围起来做到即时调用,并且减少全局变量的污染,实现代码模块化(即该代码不会因外界条件而改变结果)

var b=(function() {
var a=5;
return function() {
a++;
alert(a);
}
})();
b();    //
b();    //
alert(a)  //error

3 私有成员

var aaa=(function(){
var a =1;
function bbb(){alert(++a);}
function ccc(){alert(++a);}
return{
b:bbb,
c:ccc
} })() ;
alert(aaa.b); //
alert(aaa.c); //
alert(a); //error
alert(bbb); //error
alert(ccc); //error

aaa内的函数和变量只能通过aaa来访问,外部是访问不到的,由此实现了私有成员的创建。

4 循环 索引 作用域延伸

//有一个3个<li>标签的页面,需要绑定点击事件,弹出对应的序号。

windows.onload=function(){
var aLi=document.getElementByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = (function(i){
return function(){alert(i);}
})(i);
}
}

当然在ES6中使用let替代var也可以解决这个问题。所以在支持ES6的浏览器中能用let的地方就不要用var。

还有一个需要注意的地方:

IE下回引发内存泄漏

//假设有个id为div1的div
window.onload=function(){
var oDiv=document.getElementById('div1');
oDIv.onclick=function(){
alert(oDiv.id);
};
}

在上述情况中,DOM树中的元素被更深层级的调用,会导致关闭页面后无法释放内存的问题,最终会导致内存泄漏。

要想解决这个问题也是十分的简单,只需要在关闭界面的时候强制解除对元素的引用。即:

//假设有个id为div1的div
window.onload=function(){
var oDiv=document.getElementById('div1');
oDIv.onclick=function(){
alert(oDiv.id);
};
//以下为添加解除程序
window.onunload=function(){
oDiv.click=null;//或者oDiv=null也可以。
}
}

以上便是闭包的所有相关知识。总结一下:

1 闭包的含义:函数中嵌套函数,嵌套的内部函数可以访问外部函数的参数和变量。

2 闭包的作用:

  1 避免全局变量的污染。

  2 创建私有成员(函数和变量)。实现代码模块化

  3 作用域的延伸,也是变量常驻内存的一种体现。

 

JavaScript 再谈闭包的更多相关文章

  1. javascript --- 再谈词法分析

    javascript代码是如何执行的呢,分为六个步骤(就像把大象装进冰箱总共分几步?): 第一步:载入第一个js代码段(注:script标签对内的代码或是引用js代码,这也说明js并不是一行一行(单纯 ...

  2. JavaScript之再谈回调与闭包

    前些阵子写了几篇关于回调和闭包的博文,感觉自己都是似懂非懂,最近在项目中又碰到了类似的情况,故在此咱们来重弹js中的回调与闭包. 先说说回调: 百度百科: 回调函数就是一个通过函数指针调用的函数.如果 ...

  3. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  4. 再谈JavaScript的数据类型问题

    JavaScript的数据类型问题已经讨论过很多次了,但许多人还有许多书仍然沿用着错误的.混乱的一些观点,所以就再细讲一回. 提及这个讨论的原因在于argb同学在我的MSN博客上的一段回复,又更早的起 ...

  5. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  6. javascript面向对象之闭包

    javascript面向对象之闭包 学习javascript一段时间了,自己对闭包作出如下总结,如有某点不妥,请君指出,不胜感激! 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量 ...

  7. 如何才能通俗易懂的解释javascript里面的"闭包"?

    看了知乎上的话题 如何才能通俗易懂的解释javascript里面的‘闭包’?,受到一些启发,因此结合实例将回答中几个精要的答案做一个简单的分析以便加深理解. 1. "闭包就是跨作用域访问变量 ...

  8. Javascript中的闭包(转载)

    前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.下面是作者从作用域链慢慢讲到 ...

  9. 狗日的Javascript中的闭包

    前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.下面是作者从作用域链慢慢讲到 ...

随机推荐

  1. IntelliJ IDEA(八) :git的使用

    项目管理离不开版本控制,目前主流版本控制工具大概就是SVN和Git,至于两者有啥区别这里就不详细介绍了,如果有不明白的可以上网查资料,后期如果有机会我再开篇栏目细说,而且现在市场上Git的使用率已经远 ...

  2. Mock拦截ajax请求

    //mock拦截ajax请求 ,生成随机数据Mock.mock('./servlet/UserServlet?method=getUser',{ 'list|1-5':[{ 'username':'@ ...

  3. Java基础系列--final关键字

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8482909.html 一.概述 final是Java关键字中最常见之一,表示"最 ...

  4. C/C++语言简介之优缺点

    一.优点1.简洁紧凑.灵活方便 C语言一共只有32个关键字,9种控制语句,程序书写形式自由,区分大小写.把高级语言的基本结构和语句与低级语言的实用性结合起来.C 语言可以像汇编语言一样对位.字节和地址 ...

  5. ubuntu命令行下java工程编辑与算法(第四版)环境配置

    ubuntu命令行下java工程编辑与算法(第四版)环境配置 java 命令行 javac java 在学习算法(第四版)中的实例时,因需要安装配套的java编译环境,可是在编译java文件的时候总是 ...

  6. Spring中的注解@Service @Component @Controller @Repository区别

    @Service用于标注业务层组件, @Controller用于标注控制层组件(如struts中的action), @Repository用于标注数据访问组件,即DAO组件, @Component泛指 ...

  7. 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  8. DxPackNet 1.打开摄像头

    好久没写博客了 ,这个系列将给大家介绍.net下一个非常好用的视频控件 ------ DxPackNet, 用这个控件大家可以轻松开发出 视频会议,视频监控,远程桌面,远程教学,远程白板,视频直播,视 ...

  9. python2.x和python3.x的区别

    一.python2.x和python3.x中raw_input( )和input( )区别 1.在Python2.x中raw_input( )和input( ),两个函数都存在,其中区别为 raw_i ...

  10. 0_OpenCV3.4.0+Visual Studio2017 + win10环境配置

    研究生学习方向是计算机视觉,因此想从传统的算法开始,于是尝试安装Opencv做一些项目.在安装过程中碰到很多问题,搭建成功后立刻记录下来,一遍以后查看. 安装环境:windows10 64bit 专业 ...