要了解JavaScript中的闭包,首先重新认识一下函数。
一、函数的两个阶段
1、函数的封装阶段
(1)在内存中开辟一个存储空间,用来存储函数
(2)将程序代码存储在这个存储空间中
(3)将存储空间的内存地址,赋值给函数名称存储
2、函数的执行阶段
(1)根据存储的内存地址找到存储空间
(2)如果有形参,使用实参给之赋值
(3)预解析阶段
(4)调用存储的程序
二、重新一下函数(主要是函数的执行过程)
1、在函数封装的阶段内存中开辟的存储空间中,独立开辟一个执行空间
2、函数的程序会在这个执行空间中执行
3、当函数执行完毕之后,这个执行空间就会被销毁,那么在函数中定义的局部变量,也会一起销毁。在函数的外部无法直接调用函数的局部变量。
例如:
那么,如何定义一个不被销毁的执行空间呢?
三、定义一个不被销毁的执行空间
1、在函数的内部,返回一个引用数据类型(数组,对象,函数)
2、在函数的外部,存在一个变量来引用这个函数
例如:如下代码就是定义了一个不被销毁的执行空间
讲了这么久,那么闭包到底是什么呢?
四、闭包
1、闭包的概念
(1)闭包是指有权访问另外一个函数作用域中的变量的函数.可以理解为(能够读取其他函数内部变量的函数)
(2)闭包是函数的一种高级应用方式
(3)建立一个不被销毁的存储空间,来在函数的外部调用和使用函数内部的数据。
2、如何定义闭包
(1)定义一个函数a,返回值是另一个函数b
(2)在返回值函数b中,使用函数a定义的局部变量
(3)在函数a的外部,有变量引用函数a,并且执行返回值函数b
例如:以下代码就是定义了一个简单的闭包
3、闭包的特点
(1)不销毁执行空间
优点:延长了变量的生命周期
缺点:执行空间一直存在,会引起内存溢出,可能会导致内存泄露,被作为攻击对象
(2)在函数外部可以访问函数内部的数据
优点:使用变量数据方便
缺点:容易造成内存泄露
(3)保护私有作用域变量
优点:不会污染全局变量,确保私有作用域变量一直存在
缺点:占用内存空间
所以说,闭包最大的问题是有可能占用大量的内存空间,降低程序的执行效率,甚至有可能造成数据溢出或者数据泄露,被作为攻击对象。因此,为了保护数据的安全性,在特殊情况下,才会使用闭包。
下面列举两个闭包的案例。
例如:多种方法实现点击li标签打印内容的一个小demo
例如:利用闭包实现三个数的乘法