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 相关文章推荐
flexigrid 参数说明
Nov 23 Javascript
Javascript之this关键字深入解析
Nov 12 Javascript
jQuery中andSelf()方法用法实例
Jan 08 Javascript
设计模式中的组合模式在JavaScript程序构建中的使用
May 18 Javascript
JS动态加载脚本并执行回调操作
Aug 24 Javascript
vue loadmore 组件滑动加载更多源码解析
Jul 19 Javascript
vue2.0 axios跨域并渲染的问题解决方法
Mar 08 Javascript
浅谈webpack4 图片处理汇总
Sep 12 Javascript
JavaScript惰性载入函数实例分析
Mar 27 Javascript
一篇文章弄懂javascript中的执行栈与执行上下文
Aug 09 Javascript
微信小程序8种数据通信的方式小结
Feb 03 Javascript
vue项目中使用bpmn-自定义platter的示例代码
May 11 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 攻击方法之谈php+mysql注射语句构造
2009/10/30 PHP
PHP explode()函数用法、切分字符串
2012/10/03 PHP
PHP读取xml方法介绍
2013/01/12 PHP
解决PHP超大文件下载,断点续传下载的方法详解
2013/06/06 PHP
php微信支付接口开发程序
2016/08/02 PHP
php变量与数组相互转换的方法(extract与compact)
2016/12/02 PHP
PHP 进度条函数的简单实例
2017/09/19 PHP
PHP实现抽奖功能实例代码
2020/06/30 PHP
详解PHP中的8个魔术常量
2020/07/06 PHP
jQuery 使用手册(二)
2009/09/23 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
jquery实现动态操作select选中
2015/02/11 Javascript
jquery滚动特效集锦
2015/06/03 Javascript
谈谈JavaScript自定义回调函数
2015/10/18 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
2016/09/14 Javascript
jQuery获取Table某列的值(推荐)
2017/03/03 Javascript
微信小程序开发中的疑问解答汇总
2017/07/03 Javascript
JS隐藏号码中间4位代码实例
2019/04/09 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
2020/02/09 Javascript
vue+element 实现商城主题开发的示例代码
2020/03/26 Javascript
[00:48]DOTA2国际邀请赛公开赛报名开始 扫码开启逐梦之旅
2018/06/06 DOTA
[01:38]女王驾到——至宝魔廷新尊技能&特效展示
2020/06/16 DOTA
python脚本设置系统时间的两种方法
2016/02/21 Python
python使用xlrd与xlwt对excel的读写和格式设定
2017/01/21 Python
Python常见加密模块用法分析【MD5,sha,crypt模块】
2017/05/24 Python
Python爬虫实现爬取百度百科词条功能实例
2019/04/05 Python
PyQt5的安装配置过程,将ui文件转为py文件后显示窗口的实例
2019/06/19 Python
Django如何简单快速实现PUT、DELETE方法
2019/07/24 Python
基于python使用tibco ems代码实例
2019/12/20 Python
详解python with 上下文管理器
2020/09/02 Python
TensorFlow2.0使用keras训练模型的实现
2021/02/20 Python
a标签下载链接的简单实现
2016/09/13 HTML / CSS
中文系学生自荐信范文
2013/11/13 职场文书
幼儿园清明节活动总结
2014/07/04 职场文书
MySQL定时备份数据库(全库备份)的实现
2021/09/25 MySQL
什么是Python装饰器?如何定义和使用?
2022/04/11 Python