关于Javascript闭包与应用的详解
作者:Marshal_dj 发布时间:2024-04-23 09:09:28
标签:js,闭包,应用
前言
Javascript闭包在学习过程中一般较难理解,本文从什么是闭包,常见闭包示例,闭包作用,闭包应用及闭包问题等方面来介绍闭包,希望能给大家带来更深层次的认识,有不恰当之处请指出,谢谢。
一、什么是闭包?
闭包是指一个嵌套的内部(子)函数引用了父函数作用域中数据的函数,这就产生了闭包。
关键理解:
1. 产生闭包必须要有嵌套函数
2. 闭包是函数,并是嵌套的内部函数
3. 闭包内部函数必须要引用父函数作用域中数据
如果不满足以上条件,则不能产生闭包,接下来示例说明。
1.1闭包满足条件代码
<script>
function person(){
var name='marshal';
function student(){ //声明子函数
console.log(name);//引用父函数作用域的变量name
}
}
person();//函数执行,产生闭包
</script>
1.2闭包产生时机
<script>
function person(){
var name='marshal';//js执行此行时,产生闭包
function student(){ //声明子函数
console.log(name);//引用父函数作用域的变量name
}
student();//内部函数在外部函数调用
}
person();//函数执行,虽满足闭包条件,但未产生闭包
</script>
闭包产生时机:嵌套子函数代码块有引用父函数作用域的数据,并该嵌套子函数要执行前,创建上下文时产生闭包。或者简单说该该嵌套子函数在外部被执行时,此刻产生了闭包。
<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, 从而确保其内存在适当时候可以被回收。
来源:https://blog.csdn.net/Marshaljun/article/details/115785867
0
投稿
猜你喜欢
- 注意,要看懂这里,必须具备简单的Python数据分析知识,必须知道matplotlib的简单使用!例1:plt.subplot(221) #
- 本文实例为大家分享了python K均值聚类的具体代码,供大家参考,具体内容如下#-*- coding:utf-8 -*- #!/usr/b
- 使用 Python 对数据进行更新操作对于 es 的更新的操作,不用到 Search() 方法,而是直接使用 es 的连接加上相应的函数来操
- 我们最好从最难的问题开始:“到底什么是函数编程 (FP)?”一个答案可能会说 FP 就是您在使用例如 Lisp、Scheme、Haskell
- (1)选择最有效率的表名顺序(只在基于规则的优化器中有效):Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写
- loss函数如何接受输入值keras封装的比较厉害,官网给的例子写的云里雾里,在stackoverflow找到了答案You can wrap
- 在SQL Server数据库中,如果执行Transact-SQL时出现了错误,我们可以使用两种捕捉错误的方法解决此问题,一种是在客户端代码(
- RateLimit 限流中间件为什么需要限流中间件在大数据量高并发访问时,经常会出现服务或接口面对大量的请求而导致数据库崩溃的情况,甚至引发
- 环境配置gradio 安装 pip install gradiocv2 安装 pip install python-opencv实验原理cv
- 本文实例讲述了Python实现连接两个无规则列表后删除重复元素并升序排序的方法。分享给大家供大家参考,具体如下:# -*- coding:u
- 动态语句, bulk insert的from &n
- 下边我就简单说一下过程和原理。第一步:实现一个匿名函数并能自己执行。(function(){ })() 这个函数在一样编的好的J
- function checkPhoto(fnUpload) { var filename = fnUpload.value; alert(f
- 下面看下通过vue提供的keep-alive减少对服务器的请求次数VUE2.0中提供了一个keep-alive方法,可以用来缓存组件,避免多
- 一.作用和使用场景在mysql入库时,不能出现两条数据主键一致的情况,因为在两条数据的主键一致的情况下,mysql就会判定为待插入数据在数据
- Postgres如何存储文件postgres提供了两种不同的方式存储二进制,要么是使用bytea类型直接存储二进制,要么就是使用postgr
- 如何优雅地解析命令行选项随着我们编程经验的增长,对命令行的熟悉程度日渐加深,想来很多人会渐渐地体会到使用命令行带来的高效率。自然而然地,我们
- 1.去重示例表内容参考此文章有些 MySQL 数据表中可能存在重复的记录,有些情况我们允许重复数据的存在,但有时候我们也需要删除这些重复的数
- 1.whl包whl格式本质上是一个压缩包,里面包含了py文件,以及经过编译的pyd文件。使得可以在不具备编译环境的情况下,选择适合自己的py
- 问题描述有时候,产品让我们做的表格,会有合并列的功能,但是官方的demo略有不清晰,本文举个例子简述之。我们先看下效果图:假设产品的需求是这