JavaScript闭包详解

本文详细解释了闭包的概念,包括其产生条件、作用及生命周期,并探讨了闭包在JavaScript中的常见应用,如函数作为返回值或参数传递。同时,也提到了闭包可能导致的问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

闭包

当一个嵌套的内部函数引用了嵌套外部函数的变量,就产生了闭包。闭包是指有权访问另一个函数作用域中的变量的函数。

如何理解闭包

闭包就是嵌套的内部函数

内部函数中包含被引用的对象

产生闭包的条件

函数的嵌套(不需要调用内部函数)

内部函数引用了外部函数的数据(变量/函数)

fucntion fn1(){
	var a = 2
	var b = 'abc'
	function fn2(){ //执行函数定义就会产生闭包,但是要定义外部函数
		console.log(a)
	}
	fn2()
}
fn1()

常见的闭包

  1. 将函数作为另一函数的返回值

    fucntion fn1(){
    	var a = 2
    	function fn2(){ 
            a++
    		console.log(a)
    	}
    	return fn2
    }
    var f = fn1()
    f()//3
    f()//4
    

    这里的重点就是a是函数级作用域,理论上函数结束a就会被销毁,当变量a变成闭包的时候,a始终保存在内存里,不会随着函数的结束而自动销毁。

  2. 将函数作为实参传递给另一个函数调用

    function showDelay(msg,time){
    	setTimeout(function(){
    		alert(msg)
    	},time)
    }
    showDelay('zlearn',2000)
    

闭包的作用

如果没有闭包,函数执行完,局部变量就会释放

如果没有闭包,我们就不能再外部操作变量

  1. 可以在函数的外部访问到函数内部的局部变量。
  2. 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。

闭包的生命周期

fucntion fn1(){
    //此时闭包已经产生,因为产生了函数提升
	var a = 2
	function fn2(){ 
        a++
		console.log(a)
	}
	return fn2
}
var f = fn1()
f()//3
f()//4
f = null//闭包死亡(包含闭包的函数对象成为垃圾对象)

自定义js模块

具有特定功能的js文件

接下来我们自定义一个js模块

首先在myModule.js里面写我们要的功能,通过匿名函数立即执行,通过window.myModule向外暴露对象

myModule.js

 (function () {
      var msg = "ZLearn"
      function Bigthings() {
        console.log(msg.toUpperCase())
      }
      function Smallthings() {
        console.log(msg.toLowerCase())
      }

      //向外暴露对象
      window.myModule = {
        Bigthings: Bigthings,
        Smallthings: Smallthings
      }
    })()

html

<script type="text/javascript" src="myModule.js"></script>
<script type="text/javascript">
    var module = myModule()
    module.Bigthings()
    module.Smallthings()
</script>

闭包的缺点

  • 函数执行完之后,函数的局部变量没有释放,占用内存的时间就变长

  • 容易造成内存泄漏,泄露多了,更容易引起内存溢出

    意外的全局变量

      function a1() {
        a = 1
        console.log(a);
      }
      a1()
      console.log(a);
    //a变成了全局变量,在外部可访问
    

    没有及时清理的计时器或者回调函数

      var intervalId = setInterval(function () {
        console.log(1);
      }, 1000)
    
    //clearInterval(intervalId)不加上这句就会不会清理
    

    如何解决?

    能不用闭包就不用闭包

    及时释放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值