javascript中闭包概念与用法深入理解


Posted in Javascript onDecember 15, 2016

本文实例分析了javascript中闭包概念与用法。分享给大家供大家参考,具体如下:

1.问题的引出,什么时候会遇到闭包?

首先因为JS是没有块状作用域的,但是有函数作用域即函数作为了局部变量之间的界限,不同函数内的局部变量具有独立性,

因为JS没有块状作用域,笔者初学JS时,在事件的监听时,因为不理解JS中局部变量的作用域,犯过不少错误!

(1)JS中的变量作用域

for(var i=0;i<9;i++)
{
}
alert(i) //输出9

我们发现,虽然变量i是块状区域for()内的一个局部变量,但是我们在块级作用域for()外,依然可以得到变量i

(2)JS中的函数作用域

function abc(){
 var a=1;
}
abc();
alert(a);// 会报错,a is not defined

我们发现,在函数外调用函数后,在函数外是无法取到函数里的变量

总结:通过(1),(2),我们加深了对JS中,没有块级作用域只有函数作用域的理解!

举例:如果现在例1:

var a=1
function abc(){
 var a=2;
}
abc();
alert(a) // a=1

特别注意如果例2:

var a=1
function abc(){
a=2;
alert(a);
}
abc();//a=2

对比例1,不同之处在于例2,中 是“a=2"而不是”var a=2“

区别在于如果是var a,则表示在函数中定义变量a,如果是没有变量声明,如果直接a,则表示在全局变量中定义变量a;

2.如果引用函数内部的变量?

由1可知,JS中只存在函数作用域,那么我们如何才能在拿到函数中定义的变量呢?

根据JS的语法规则:内部函数(或者内部对象)中,可以访问外部函数中的变量。

什么意思呢?举例说明例1:

function abc(){
 var a=1;
 !function(){
 alert(a)
} ()
} //此时不会报错,a=1

再举一个例子(内部对象的例子)例2:

var o={
 a=1,
 myfun:function(){
 return this.a
}
}

则alert(o.myfun())得到的值为1,现在我们大概了解了如何访问函数(或者对象,其实函数的本身也是对象)中的变量!

3.什么是闭包?

我的理解就定义在一个函数内部的函数!

闭包是函数内部与外部之间的桥梁!

即内部函数在定义它的外部使用时,就创建了一个闭包!

我们知道,一般情况下,当函数被调用完,内存会被释放,但是应用于函数闭包比如

function abc1(){
 var a=1;
function abc2(){
 a++;
}
return abc2()
}

当我们调用abc1()函数后,因为abc1函数的中又调用了abc2()函数,因此函数abc1()中的变量在子函数中被调用,所以在父函数abc1()调用结束后

变量a的内存空间并不会被释放!

为什么GC机制无法回收abc1()函数中的变量a,  因为首先我们在全局中调用了函数abc1(),我们设全局对象为c,abc1()对象为b,同时我们在对象b

即函数abc1()中又调用了函数abc2(),设abc2(0为a。

再次理解这种关系    c中调用了b,b中又调用了a,JS中规定当a,b对象两两互相引用,并且a,b中又有一个被a,b函数之外的对象c引用时,GC机制不执行垃圾回收(变量清空)!

由此我们引出了闭包的重要作用:

如果内部函数在其外部被调用,则会产生闭包,闭包用于保存某些变量的值,不会被垃圾回收机制回收!

4.闭包的缺点

因为使用闭包后,某些变量会在函数调用之后持续的保持在内存中,因此滥用闭包会导致内存泄漏!

5.扩展应用,加深对于闭包的理解!

var o={
 a:1;
myfunc:function(){
return function(){
 return this.a;
}
}
alert(o.myfunc()()); // a is not defined
}

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
IE6弹出“已终止操作”的解决办法
Nov 27 Javascript
jQuery右键菜单contextMenu使用实例
Sep 28 Javascript
JS排序方法(sort,bubble,select,insert)代码汇总
Jan 30 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
Oct 18 Javascript
AngularJS控制器之间的通信方式详解
Nov 03 Javascript
angularjs中使用ng-bind-html和ng-include的实例
Apr 28 Javascript
js实现点击切换checkbox背景图片的简单实例
May 08 Javascript
基于iScroll实现内容滚动效果
Mar 21 Javascript
react 兄弟组件如何调用对方的方法示例
Oct 23 Javascript
JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解
Dec 12 Javascript
vue 弹窗时 监听手机返回键关闭弹窗功能(页面不跳转)
May 10 Javascript
vue实现中部导航栏布局功能
Jul 30 Javascript
javascript读取文本节点方法小结
Dec 15 #Javascript
EditPlus中的正则表达式 实战(4)
Dec 15 #Javascript
jQuery validate插件功能与用法详解
Dec 15 #Javascript
EditPlus 正则表达式 实战(3)
Dec 15 #Javascript
js实现点击每个li节点,都弹出其文本值及修改
Dec 15 #Javascript
EditPlus中的正则表达式 实战(2)
Dec 15 #Javascript
js代码实现下拉菜单【推荐】
Dec 15 #Javascript
You might like
PHP的宝库目录--PEAR
2006/10/09 PHP
工厂模式在Zend Framework中应用介绍
2012/07/10 PHP
使用Curl进行抓取远程内容时url中文编码问题示例探讨
2013/10/29 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
2019/05/27 PHP
Three.js源码阅读笔记(光照部分)
2012/12/27 Javascript
node.js中的fs.truncateSync方法使用说明
2014/12/15 Javascript
mvvm双向绑定机制的原理和实现代码(推荐)
2016/06/07 Javascript
Javascript中关于Array.filter()的妙用详解
2016/12/04 Javascript
使用Vue组件实现一个简单弹窗效果
2018/04/23 Javascript
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
2018/05/09 jQuery
了解ESlint和其相关操作小结
2018/05/21 Javascript
微信小程序项目实践之验证码倒计时功能
2018/07/18 Javascript
js实现网页同时进行多个倒计时功能
2019/02/25 Javascript
微信小程序监听用户登录事件的实现方法
2019/11/11 Javascript
通过原生vue添加滚动加载更多功能
2019/11/21 Javascript
详解JavaScript 事件流
2020/09/02 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
python字符串与url编码的转换实例
2018/05/10 Python
Flask之flask-session的具体使用
2018/07/26 Python
浅述python2与python3的简单区别
2018/09/19 Python
Django框架自定义模型管理器与元选项用法分析
2019/07/22 Python
Python 实现大整数乘法算法的示例代码
2019/09/17 Python
win7下 python3.6 安装opencv 和 opencv-contrib-python解决 cv2.xfeatures2d.SIFT_create() 的问题
2019/10/24 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
Pycharm最常用的快捷键及使用技巧
2020/03/05 Python
在 Pycharm 安装使用black的方法详解
2020/04/02 Python
南京软件公司的.net程序员笔试题
2014/08/31 面试题
大学校园毕业自我鉴定
2014/01/15 职场文书
好人好事演讲稿
2014/09/01 职场文书
幸福家庭事迹材料
2014/12/20 职场文书
新闻稿格式范文
2015/07/18 职场文书
《黄道婆》教学反思
2016/02/22 职场文书
如何正确理解python装饰器
2021/06/15 Python
Python办公自动化之教你如何用Python将任意文件转为PDF格式
2021/06/28 Python
教你使用VS Code的MySQL扩展管理数据库的方法
2022/01/22 MySQL
Ruby处理CSV数据方法详解
2022/04/18 Ruby