JavaScript 再谈闭包
之前有整理过一版关于闭包的概念,但感觉思路不是很清晰,是临时想起一些例子来讲的,今天再次来讲一下闭包。
闭包:
函数嵌套函数,内部函数可以引用外部函数的参数和变量
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 再谈闭包的更多相关文章
- javascript --- 再谈词法分析
javascript代码是如何执行的呢,分为六个步骤(就像把大象装进冰箱总共分几步?): 第一步:载入第一个js代码段(注:script标签对内的代码或是引用js代码,这也说明js并不是一行一行(单纯 ...
- JavaScript之再谈回调与闭包
前些阵子写了几篇关于回调和闭包的博文,感觉自己都是似懂非懂,最近在项目中又碰到了类似的情况,故在此咱们来重弹js中的回调与闭包. 先说说回调: 百度百科: 回调函数就是一个通过函数指针调用的函数.如果 ...
- 浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
- 再谈JavaScript的数据类型问题
JavaScript的数据类型问题已经讨论过很多次了,但许多人还有许多书仍然沿用着错误的.混乱的一些观点,所以就再细讲一回. 提及这个讨论的原因在于argb同学在我的MSN博客上的一段回复,又更早的起 ...
- 让你分分钟学会Javascript中的闭包
Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...
- javascript面向对象之闭包
javascript面向对象之闭包 学习javascript一段时间了,自己对闭包作出如下总结,如有某点不妥,请君指出,不胜感激! 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量 ...
- 如何才能通俗易懂的解释javascript里面的"闭包"?
看了知乎上的话题 如何才能通俗易懂的解释javascript里面的‘闭包’?,受到一些启发,因此结合实例将回答中几个精要的答案做一个简单的分析以便加深理解. 1. "闭包就是跨作用域访问变量 ...
- Javascript中的闭包(转载)
前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.下面是作者从作用域链慢慢讲到 ...
- 狗日的Javascript中的闭包
前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.下面是作者从作用域链慢慢讲到 ...
随机推荐
- 深入分析Java ClassLoader的原理(转)
一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程 ...
- 图书管理系统【JavaWeb:部署开发环境、解决分类、图书、前台页面模块】
前言 巩固Servlet+JSP开发模式,做一个比较完整的小项目. 成果图 该项目包含了两个部分,前台和后台. 前台用于显示 后台用于管理 该项目可分为5个模块来组成:分类模块,用户模块,图书模块,购 ...
- 如何在CentOS 7上部署Google BBR【搬运、机翻】
如何在CentOS 7上部署Google BBR 本文章搬运自 https://www.vultr.com/docs/how-to-deploy-google-bbr-on-centos-7 [注:文 ...
- 转:【web前端开发】浏览器兼容性处理大全
解决思路: ①.写代码的时候遵循W3C标准,按照最新稳定版本的IE或WebKit内核浏览器进行编码 ②.遇到部分无法全面解决浏览器兼容的时候,采取CSS的hack手段进行针对性微调.简单的说,CSS ...
- filter-api文档
git地址:https://github.com/jiqianqin/filters 不断优化中,欢迎加入讨论- filter-tags 效果图: 参数 说明 格式 备注 data 展示的数据 [{ ...
- 10分钟入门spark
Spark是硅谷各大公司都在使用的当红炸子鸡,而且有愈来愈热的趋势,所以大家很有必要了解学习这门技术.本文其实是笔者深入浅出hadoop系列的第三篇,标题里把hadoop去掉了因为spark可以不依赖 ...
- 使用SpringSecurity保护你的Eureka.
因为注册中心基本上都是自己的应用在使用,应用不是特别多,可以写死,如果应用很多,那么就写入数据库把 pom <dependency> <groupId>org.springfr ...
- 动态添加数据源,根据用户登录切换数据库.编程式Spring事务.
根据用户注册,系统自动创建私有数据库,用户登录,动态添加数据源到Spring数据路由,Session超时删除数据源 好处:当数据量大的时候,类似水平切割效果,效率会高一些 坏处:数据源切换,Sprin ...
- 将DataSet转化成XML格式的String类型,再转化回来。
/// <summary> /// 获取DataSet的Xml格式 /// </summary> public static string GetDataSetXml(this ...
- Zookeeper笔记3——原理及其安装使用
Zookeeper到底能干什么? 1.配置管理:这个好理解.分布式系统都有好多机器,Zookeeper提供了这样的一种服务:一种集中管理配置的方法,我们在这个集中的地方修改了配置,所有对这个配置感兴趣 ...