闭包

闭包(closure)

1.如何产生闭包?

​ 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数),内部函数被定义时(即外部函数被执行时),就产生了闭包。

​ 外部函数执行几次就产生了几个闭包

2.闭包到底是什么?
		* 使用chrome查看
		* 理解一:闭包是嵌套的内部函数(绝大多数人)
		* 理解二:包含被引用变量(函数)的对象(极少数人)
		* 注意:闭包存在于嵌套的内部函数中		
3.产生闭包的条件?
  • 函数嵌套
  • 内部函数引用了外部函数的数据(变量/函数)

如下代码可以产生闭包

function fn1 () {
	var a = 2
	function fn2 () { //执行函数定义时才会产生闭包(不用调用内部函数)
  		console.log(a)
	}
}
fn1() //调用一次产生一个闭包

注意:以下代码执行到第3行时,内部函数才被定义,此时才产生闭包

function fn1 () {
	var a = 2
	var fn2 = function() { //执行函数定义时才会产生闭包(不用调用内部函数)
  		console.log(a)
	}
}
fun1()
4.闭包的经典应用

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

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

​ 外部函数执行几次就产生了几个闭包,这里 fn1 只执行了 1 次,所以产生 1 个闭包。

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

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

3、利用闭包实现:点击li输出对应的索引

<ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
var aLi = document.querySelectorAll("li");
for (var i = 0; i < aLi.length; i++) {
            (function (i) {
                aLi[i].onclick = function () {
                    console.log(i);
                }
            })(i)
        }
5.闭包的作用

使函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)

让函数外部可以操作(读写)到函数内部的数据(变量/数据)

问题???

​ 函数执行完后,函数内部声明的局部变量是否还存在?

​ 答:一般是不存在了,存在于闭包中的变量才可能存在

​ 在函数外部能直接访问函数内部变量吗?

​ 答:不能,但我们可以通过闭包让外部操作它

6.闭包的生命周期

产生:在嵌套内部函数定义执行完时就产生了(不是在调用)

死亡:在嵌套的内部函数成为垃圾对象时

7.闭包的优点——自定义JS模块
  • 具有特定功能的js文件

  • 将所有的数据和功能都封装在一个函数内部(私有的)

  • 只向外暴露一个包含n个方法的对象和函数

  • 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

创建一个myModule.js文件

function myModule(){
    var msg = 'My atguigu'
    function doSomething(){
        console.log('doSomething()' + msg.toUpperCase())
    }
    function doOtherthing(){
        console.log('doOtherthing()' + msg.toLowerCase())
    }
    return {
        doSomething:doSomething,
        doOtherthing:doOtherthing
    }
}

在index.html文件中引用myModule.js文件

<!DOCTYPE html>
<html lang='en'>
    <head>
    <meta charset='UTF-8'>
    <title>闭包的应用——自定义的JS模块</title>
    </head>
	<body>
    	<script type='text/javascript' src='myModule.js'></script>
		<script type='text/javascript'>
            var module = myModule()
				module.doSomething()
				module.doOtherthing()
        </script>
    </body>
</html>

通过函数自调用,将函数/数据暴露在window对象上,这样可以在inde.html直接写函数/名字使用不用对象.函数/变量的形式

(function(window){
    var msg = 'My LoveCode'
    function doSomething(){
        console.log('doSomething()' + msg.toUpperCase())
    }
    function doOtherthing(){
        console.log('doOtherthing()' + msg.toLowerCase())
    }
    window.myModule2 = {
        doSomething:doSomething,
        doOtherthing:doOtherthing
    }
})(wondow)
8.闭包的缺点

缺点:

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

容易造成内存泄漏

解决:

能不用闭包就不用

及时释放

内存溢出:

​ 一种程序运行出现的错误

​ 当程序运行需要的内存超过了剩余的内存时,就会抛出内存溢出的错误

内存泄漏

​ 占用的内存没有及时释放

​ 内存泄漏积累多了就容易导致内存溢出

​ 常见的内存泄漏:

​ 1 意外的全局变量(比如在函数内部不使用var声明的变量)

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

​ 3 闭包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值