理解javascript闭包


Posted in Javascript onDecember 15, 2015

什么是javascript闭包?
javascript允许使用内部函数,内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
简单的javascript闭包例子:

<script>
  function f1(){

var n=999;


nAdd=function(){n+=1}


function f2(){



alert(n);


}


return f2;

}

var result=f1();

result(); // 999

nAdd();

result(); // 1000
</script>

在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
 闭包的应用:

var singleton = function () {
  var privateVariable;
  function privateFunction(x) {
    ...privateVariable...
  }
 
  return {
    firstMethod: function (a, b) {
      ...privateVariable...
    },
    secondMethod: function (c) {
      ...privateFunction()...
    }
  };
}();

 这个单件通过闭包来实现。通过闭包完成了私有的成员和方法的封装。匿名主函数返回一个对象。对象包含了两个方法,方法1可以方法私有变量,方法2访问内部私有函数。需要注意的地方是匿名主函数结束的地方的'()',如果没有这个'()'就不能产生单件。因为匿名函数只能返回了唯一的对象,而且不能被其他地方调用。这个就是利用闭包产生单件的方法。

闭包的优势:
(1)不增加额外的全局变量,
(2)执行过程中所有变量都是在匿名函数内部。
闭包的缺点:
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

本文就为大家介绍这里,如果大家对javascript闭包还是不够了解,请阅读相关文章进行补充学习,谢谢大家的阅读。

Javascript 相关文章推荐
基于JQuery 的消息提示框效果代码
Jul 31 Javascript
JavaScript 选中文字并响应获取的实现代码
Aug 28 Javascript
基于jQuery的图片左右无缝滚动插件
May 23 Javascript
jQuery中[attribute*=value]选择器用法实例
Dec 31 Javascript
为什么JS中eval处理JSON数据要加括号
Apr 13 Javascript
jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
Aug 05 Javascript
详解Angular2表单-模板驱动的表单(Template-Driven Forms)
Aug 04 Javascript
Angular实现的敏感文字自动过滤与提示功能示例
Dec 29 Javascript
微信打开网址添加在浏览器中打开提示的办法
May 20 Javascript
vue3.0中的双向数据绑定方法及优缺点
Aug 01 Javascript
JS函数进阶之prototy用法实例分析
Jan 15 Javascript
jquery实现的放大镜效果示例
Feb 24 jQuery
jQuery检测滚动条是否到达底部
Dec 15 #Javascript
js实现根据身份证号自动生成出生日期
Dec 15 #Javascript
浅析javascript的return语句
Dec 15 #Javascript
轻松学习Javascript闭包函数
Dec 15 #Javascript
Javascript基于AJAX回调函数传递参数实例分析
Dec 15 #Javascript
javascript实现html页面之间参数传递的四种方法实例分析
Dec 15 #Javascript
js编写贪吃蛇的小游戏
Aug 24 #Javascript
You might like
php将会员数据导入到ucenter的代码
2010/07/18 PHP
360通用php防护代码(使用操作详解)
2013/06/18 PHP
mac系统下安装多个php并自由切换的方法详解
2017/04/21 PHP
JS对URL字符串进行编码/解码分析
2008/10/25 Javascript
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
js过滤数组重复元素的方法
2010/09/05 Javascript
jquery html动态生成select标签出问题的解决方法
2013/11/20 Javascript
中止javascript执行的方法
2014/02/14 Javascript
JavaScript中的函数重载深入理解
2014/08/04 Javascript
简单谈谈javascript中的变量、作用域和内存问题
2015/08/30 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
关于JavaScript数组你所不知道的3件事
2016/08/24 Javascript
Node.js编写CLI的实例详解
2017/05/17 Javascript
springmvc接收jquery提交的数组数据代码分享
2017/10/28 jQuery
基于js中的存储键值对以及注意事项介绍
2018/03/30 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
jquery自定义组件实例详解
2020/12/31 jQuery
[01:04:48]VGJ.S vs TNC Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
基于python编写的微博应用
2014/10/17 Python
Python自动重试HTTP连接装饰器
2015/04/28 Python
Anaconda入门使用总结
2018/04/05 Python
浅析python中numpy包中的argsort函数的使用
2018/08/30 Python
Python 新建文件夹与复制文件夹内所有内容的方法
2018/10/27 Python
Django框架ORM数据库操作实例详解
2019/11/07 Python
Python GUI自动化实现绕过验证码登录
2020/01/10 Python
Python第三方包之DingDingBot钉钉机器人
2020/04/09 Python
如何学习Python time模块
2020/06/03 Python
在pytorch中动态调整优化器的学习率方式
2020/06/24 Python
Old Navy加拿大官网:美式休闲服饰品牌
2017/09/26 全球购物
白俄罗斯大卖场:21vek.by
2019/07/25 全球购物
平面设计自荐信
2013/10/07 职场文书
《哪吒闹海》教学反思
2014/02/28 职场文书
公司开除员工通知
2015/04/22 职场文书
小程序实现悬浮按钮的全过程记录
2021/10/16 HTML / CSS
sqlserver连接错误之SQL评估期已过的问题解决
2022/03/23 SQL Server