关于Javascript闭包与应用的详解


Posted in Javascript onApril 22, 2021

前言

Javascript闭包在学习过程中一般较难理解,本文从什么是闭包,常见闭包示例,闭包作用,闭包应用及闭包问题等方面来介绍闭包,希望能给大家带来更深层次的认识,有不恰当之处请指出,谢谢。

一、什么是闭包?

闭包是指一个嵌套的内部(子)函数引用了父函数作用域中数据的函数,这就产生了闭包。

关键理解:

1. 产生闭包必须要有嵌套函数
2. 闭包是函数,并是嵌套的内部函数
3. 闭包内部函数必须要引用父函数作用域中数据

如果不满足以上条件,则不能产生闭包,接下来示例说明。

1.1闭包满足条件代码

<script>
			function person(){
				var name='marshal';
				function student(){ //声明子函数
					console.log(name);//引用父函数作用域的变量name
				}
			}
			person();//函数执行,产生闭包
		</script>

关于Javascript闭包与应用的详解

1.2闭包产生时机

<script>
			function person(){
				var name='marshal';//js执行此行时,产生闭包
				function student(){ //声明子函数
					console.log(name);//引用父函数作用域的变量name
				}
				student();//内部函数在外部函数调用
			}
			person();//函数执行,虽满足闭包条件,但未产生闭包
		</script>

关于Javascript闭包与应用的详解

闭包产生时机:嵌套子函数代码块有引用父函数作用域的数据,并该嵌套子函数要执行前,创建上下文时产生闭包。或者简单说该该嵌套子函数在外部被执行时,此刻产生了闭包。

<script>
			function person(){
				var name='marshal';
				function student(){
					console.log(name);  //该方法代码内为闭包代码
				}
				return student;
			}
			var p=person();//因创建子函数对像,此时产生第一次闭包,并将子函数student返回给p,由于p没有消失,子函数引用的变量name,一直在内存在存储,直到将p=null,进行回收
			p();//执行子函数的闭包代码块,输出"marhsal"
			p();//第二次执行子函数的闭包代码块,输出"marhsal"
			person();//第二次创建子函数调对象,此时产生第二次闭包,但不执行子函数student代码块      
		</script>

二、常见闭包示例

2.1 子函数做为实参传递

<script>
			function setTimeoutTest(message,time){
				setTimeout(function(){
					alert(message);//嵌套子函数引用父函数变量message,产生闭包
				},time);
			}  
			setTimeoutTest('提示信息',1000);
		</script>

2.2 计数器使用(函数返回)

<script>
				function count(){
					var i=1;
					function add(){
						i++;
						console.log(i);
					}
					return add;
				}
				var c=count();//生产闭包
				c();//2
				c();//3
				c();//4
		</script>

三、闭包作用

3.1 闭包作用

1)子函数引用父函数的变量或函数,生命周期延长

2)其变量或函数一直存在,外部可以访问函数内部的值

<script>
			function count(){
				var i=1;
				function add(){
					i++;
					console.log(i);
				}
				return add;
			}
			var c=count();
			c();//2
			c();//3  i的生命周期延长
	</script>

四、闭包应用

4.1 自定义封装js代码

外部js代码  out.js  实现自加与自减
(function count(){
	var i=1;
	function add(){
		i++;
		console.log(i);
	}
	function subtract(){
		i--
		console.log(i);
	}
	window.count={
		add:add,
		subtract:subtract
	}
})();
引用 out.js代码
<script src=out.js></script>
		<script>
			count.add(); //2
			count.subtract();//1
			count.subtract();//0
		</script>

五、闭包问题

5.1 闭包与this

<script>
     var name="marshal"; //创建全局变量
	 var person={
		 name:"leo",
		 getName:function(){ //返回匿名函数
			 return function(){  //返回this.name
				return this.name;  //返回字符串
			 }
		 }
	 };
	 alert(person.getName()()); //输出marshal,内部函数不可能直接访问外部函数this
	 
</script>

解决方法

<script>
	     var name="marshal";
			 var person={
				 name:"leo",
				 getName:function(){
					 var that=this;//把this保存到闭包可以访问的另一个变量中
					 return function(){
						return that.name;
					 }
				 }
			 };
			 alert(person.getName()());//that 指向person,而不是window
	</script>

5.2 内存泄露

在使用闭包时,因变量一直存在,需要解除对象的引用,将对象设置为null, 从而确保其内存在适当时候可以被回收。

到此这篇关于关于Javascript闭包与应用的详解的文章就介绍到这了,更多相关js闭包与应用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
ExtJS 2.0实用简明教程 之Border区域布局
Apr 29 Javascript
jquery获得当前html页面源码的方法
Jul 14 Javascript
浅谈js使用in和hasOwnProperty获取对象属性的区别
Apr 27 Javascript
JavaScript 完成注册页面表单校验的实例
Aug 19 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
Dec 14 Javascript
10个在JavaScript开发中常遇到的BUG
Dec 18 Javascript
关于vue单文件中引用路径的处理方法
Jan 08 Javascript
vue实现a标签点击高亮方法
Mar 17 Javascript
原生JS实现的碰撞检测功能示例
May 18 Javascript
说说Vue.js中的functional函数化组件的使用
Feb 12 Javascript
JavaScript封闭函数及常用内置对象示例
May 13 Javascript
浅谈微信小程序列表埋点曝光指南
Oct 15 Javascript
vue首次渲染全过程
使用 JavaScript 制作页面效果
Apr 21 #Javascript
一道JS算法面试题——冒泡、选择排序
Apr 21 #Javascript
吃通javascript正则表达式
Apr 21 #Javascript
Ajax是什么?Ajax高级用法之Axios技术
在HTML5 localStorage中存储对象的示例代码
Apr 21 #Javascript
canvas多重阴影发光效果实现
You might like
数据库的日期格式转换
2006/10/09 PHP
php实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
PHP 数组遍历方法大全(foreach,list,each)
2010/06/30 PHP
利用jquery操作select下拉列表框的代码
2010/06/04 Javascript
js限制文本框为整数和货币的函数代码
2010/10/13 Javascript
基于jquery 的一个progressbar widge
2010/10/29 Javascript
PHP PDO操作总结
2014/11/17 Javascript
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
2015/01/13 Javascript
jQuery中serializeArray()与serialize()的区别实例分析
2015/12/09 Javascript
jQuery中的siblings用法实例分析
2015/12/24 Javascript
浅谈JS中json数据的处理
2016/06/30 Javascript
Bootstrap实现input控件失去焦点时验证
2016/08/04 Javascript
基于Node.js的WebSocket通信实现
2017/03/11 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
vue axios登录请求拦截器
2018/04/02 Javascript
微信{"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
2018/10/12 Javascript
vue cli使用融云实现聊天功能的实例代码
2019/04/19 Javascript
手写Vue弹窗Modal的实现代码
2019/09/11 Javascript
原生js实现无缝轮播图效果
2021/01/28 Javascript
[01:00:53]OG vs IG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
教你如何在Django 1.6中正确使用 Signal
2014/06/22 Python
python提取页面内url列表的方法
2015/05/25 Python
Android应用开发中Action bar编写的入门教程
2016/02/26 Python
Python实现单词翻译功能
2017/06/06 Python
python pands实现execl转csv 并修改csv指定列的方法
2018/12/12 Python
Python实现E-Mail收集插件实例教程
2019/02/06 Python
Python操作SQLite/MySQL/LMDB数据库的方法
2019/11/07 Python
使用Keras画神经网络准确性图教程
2020/06/15 Python
成品库仓管员岗位职责
2014/04/06 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
2015年小学生自我评价范文
2015/03/03 职场文书
2015年学生管理工作总结
2015/05/26 职场文书
教师节简报
2015/07/20 职场文书
煤矿施工安全协议书
2016/03/22 职场文书
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL
SQL实现LeetCode(178.分数排行)
2021/08/04 MySQL