JavaScript基础——闭包

闭包简介

闭包的作用

闭包可以保留变量的状态

闭包可以让变量私有化

闭包的缺点


闭包简介

在JavaScript中,重复声明同一个变量会导致变量冲突,在这个时候可以使用闭包创建独立的执行环境。

在JavaScript中,闭包是指封闭的执行环境,指的是一个函数能够记住并访问其创建时所在的作用域,即使这个函数在其原始作用域之外被执行,也就是说一个函数(内部)有权访问另一个(外部)函数作用域的变量。闭包通常由嵌套函数创建,即一个函数内部定义了另一个函数。外层函数可以返回内层函数,而内层函数可以访问外层函数的变量。

语法如下:

javascript 复制代码
        function 函数名称() {
            代码块
            return function () {
                代码块
            }
        }

定义函数f1,定义f1函数局部作用域的变量user,再定义一个匿名函数作为f1函数的返回值,匿名函数可以访问user,也就是内部函数可以访问外部函数作用域的变量。

javascript 复制代码
        // 局部变量
        function f1() {
            var user = '小明';
            function foo() {
                console.log("hello" + user);
            }
            // 函数也是数据,把这个函数作为f1的返回值,调用f1可以获取foo
            return foo;
        }

        // 由f1所形成的封闭环境,叫做闭包
        var bibao1 = f1();
        bibao1();

将f1改为直接使用返回函数return function()的形式。

javascript 复制代码
        function f2() {
            var user = '小明';
            return function () {
                console.log("hello2" + user);
            }
        }
        var bibao2 = f2();
        bibao2();

定义一个add()函数,定义局部变量num,在函数中写一个内部函数作为返回值,如果不写这个内部函数的话,每次看到的数值只有0(初始值)。

add()函数返回了一个闭包,这个闭包能够访问并修改add函数作用域内的变量num。每次调用这个闭包时,它都会增加num的值并打印出来。

javascript 复制代码
        function add() {
            var num = 0;
            return function () {
                num++;
                console.log('数字:', num);
            }
        }

创建两个闭包的实例bibao3和bibbao4,每次调用add函数,每个闭包都会创建一个新的num变量(相当于开辟新的内存空间),bibao3和bibao4直接是相互独立的。

既然调用函数是函数名称()的形式,为什么不能直接用函数名称()()访问闭包呢?

闭包的作用

闭包可以保留变量的状态

创建闭包时,会创建一个新的内存空间,都会开辟独立的内存空间,在闭包中的变量可以记住当前的状态,再次使用闭包时,闭包会保留之前的状态。

在前面的案例中,每次bibao3()或者bibao4(),都会按照上一次的值进行自增。

闭包可以让变量私有化

每次创建一个新的闭包,就会开辟独立的内存空间,闭包的变量都是私有的。

在前面的案例中,每次bibao3()或者bibao4(),bibao3()和bibao4()的num值是不相同的。

闭包的缺点

闭包虽然在JavaScript中提供了强大的封装和数据保护能力,但也存在一些缺点。首先,由于闭包能够捕获并长期持有其创建时的作用域中的变量,这可能导致内存使用增加,尤其是在大量创建闭包的情况下,可能会引起内存泄漏。其次,闭包可能会形成难以追踪的循环引用,这会阻碍JavaScript垃圾回收机制的效率,从而影响程序的性能。此外,闭包的使用如果不当,会增加代码的复杂性,使得理解和维护变得更加困难。因此,开发者在使用闭包时需要谨慎,确保在不需要时及时释放引用,避免不必要的内存占用,并合理组织代码以提高可读性和可维护性。

相关推荐
小大宇几秒前
vue知识点9-标签上的ref
前端·javascript·vue.js
2601_9495758611 分钟前
JSON5 跨端三方库仓颉适配全流程
前端·javascript·flutter
泡泡糖的中文规格书14 分钟前
HDLbits 2.2 学习笔记 · 多路复用器
java·开发语言
John_Hui17 分钟前
第 3 篇:配置 JDK 17 环境
java·开发语言·ubuntu
充值内卷31 分钟前
C++单文件迷宫游戏:TauriCPP 开发全记录
开发语言·c++·游戏
Antruly32 分钟前
C++ Web 开发选型漫谈:从 Drogon 到 libuvcpp + uvp,八个项目的定位、兼容性与务实排名
开发语言·前端·c++
EnCi Zheng36 分钟前
AI Agent工具调用防护层怎么写-一份能直接跑的Python四层拦截实现
大数据·开发语言·python
香蕉大香蕉(06敬畏市场)1 小时前
高频八股 · Java 并发编程(10):异步、ThreadLocal 与虚拟线程(收官)
java·开发语言·网络·jvm·python·ai·实习
念何架构之路1 小时前
Go reflect包值操作 Value 的读写、可设置性与 interface 布局
开发语言·后端·golang
云中飞鸿1 小时前
.Net和C#有什么关系?(从C++视角观察)
开发语言·c#·.net