闭包`closure`/实际应用-数据安全

01-闭包-closure

    <script>
        // 闭包:closure,函数内部用到了函数外部的数据(变量存着),这种现象就叫做闭包现象

        let arr = [1, 2, 3]

        function getArrMax() {
            let max = -Infinity

            for (let i = 0; i < arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i]
                }
            }

            return max
        }

        // 函数内部arr用到的是函数外部的变量:产生闭包现象
        // 上述闭包:广义闭包(定义比较宽松)

        // 狭义闭包:面试的时候想要得到的结果是狭义闭包

        // 狭义闭包条件
        // 1. 函数内部定义了局部变量
        // 2. 函数返回一个内部函数,内部函数里面用到了外部函数的变量
        function outer() {
            console.log('outer函数')
            // 局部变量
            let arr = ['a', 'b', 'c']

            // 内部函数
            let inner = function () {
                // 内部函数使用到了外部函数的变量
                // 狭义闭包
                console.log(arr)
            }

            return inner
        }

        // 函数运行的步骤
        // 1. 找到函数
        // 2,开辟内存运行函数
        // 3. 运行结束应该销毁函数所占用的内存
        let res = outer()

        // 57行:等代码执行到这,说明上面代码执行应该结束了:outer()函数占用的内存应该销毁掉了
        // console.log(res)
        res()

        // 闭包的优缺点
        // 1. 优点:数组定义在函数内部:数据是安全的(不会被修改,也不能被污染)
        // 2. 缺点:函数虽然运行结束,但是因为内部函数还需要用到外部函数的数组变量:不能被销毁:占用内存
    </script>

注意:
1.闭包:closure,函数内部用到了函数外部的数据(变量存着),这种现象就叫做闭包现象
2. // 函数内部arr用到的是函数外部的变量:产生闭包现象
// 上述闭包:广义闭包(定义比较宽松)

    // 狭义闭包:面试的时候想要得到的结果是狭义闭包

    // 狭义闭包条件
    // 1. 函数内部定义了局部变量
    // 2. 函数返回一个内部函数,内部函数里面用到了外部函数的变量

// 闭包的优缺点 // 1. 优点:数组定义在函数内部:数据是安全的(不会被修改,也不能被污染) // 2. 缺点:函数虽然运行结束,但是因为内部函数还需要用到外部函数的数组变量:不能被销毁:占用内存



02-闭包-实际应用

<body>
    <button>按钮</button>
    <h1></h1>
    <script>
        // 函数内部使用外部变量(广义),内部函数使用了外部函数的局部变量(狭义)

        // 需求:将数组中的数据,在点击后轮番显示到h1中
        let arr = ['金', '木', '水', '火', '土']

        // 1. 获取相关元素:按钮,h1
        let btn = document.querySelector('button')
        let h1 = document.querySelector('h1')
        // 2. 定义一个变量记录下标:给h1默认显示第一个元素
        let index = 0
        h1.innerText = arr[index]
        // 3. 给按钮做点击事件
        btn.onclick = () => {
            // 4. 事件处理:修改index下标,++;将新的index对应的数组元素显示到h1中
            index++

            if (index == arr.length) index = 0

            h1.innerText = arr[index]
        }

    </script>
</body>



03-闭包-实际应用-数据安全

<body>
    <button>按钮</button>
    <h1></h1>
    <script>
        (function () {
            // 函数内部使用外部变量(广义),内部函数使用了外部函数的局部变量(狭义)

            // 需求:将数组中的数据,在点击后轮番显示到h1中

            // 安全解决:由全局变成局部
            // 1. 将数组放到函数中:变成局部变量(安全)
            const getElement = () => {
                const arr = ['金', '木', '水', '火', '土']
                // 2. 函数实现的功能:动态的从数组中取出数据,返回给外部使用
                // 2.1 定义一个局部变量:保存下标
                let index = -1
                // 2.2 定义一个内部函数:负责处理数据
                return () => {
                    // 可以使用外部局部变量
                    index++

                    // 包要整安全
                    if (index == arr.length) index = 0

                    // 返回index对应的数组元素
                    return arr[index]
                }
            }

            // 剩下的就是业务问题:用户到底是点击操作还是别的?用户到底是显示到h1中还是别的地方?
            // 第一次显示数据
            let getArrInfo = getElement()

            document.querySelector('h1').innerText = getArrInfo()

            document.querySelector('button').onclick = () => {
                document.querySelector('h1').innerText = getArrInfo()


                // 如何解决闭包占用内存的问题?
                // 解决方案:释放对内部函数占用的变量:JS垃圾回收的机制是:一旦某个数据不会被其他变量占着:系统会自动回收内存
                // getArrInfo = null

                // 不是所有的闭包都必须释放
                // 如果必要只为了使用一次(保证数据安全),用完一定要记得销毁

                // 如果是用户需要不断使用:不可被效果
            }
        })()
    </script>
</body>

注意:
1. 闭包:解决安全问题(数据安全)
2. 闭包:函数内部套函数,狭义闭包
3. 闭包:解决了安全问题,代价
3.1 代码复杂度增加(开发难度增加)
3.2 长期占用内存
4. 占用内存的解决方案:将指向内部函数的变量销毁
4.1 内部函数没有被变量引用:会被内存回收,占用的外部局部变量也会被回收
4.2 不一定需要销毁:不断使用的就不能销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值