【JavaScript15】闭包

发布时间 2023-08-06 21:17:10作者: Tony_xiao

什么是闭包

  • 闭包(closure)是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰,即形成一个不销毁的栈环境。
  • 闭包的特性:
    • 函数嵌套函数
    • 内部函数可以访问外部函数的变量
    • 参数和变量不会被回收。

为什么要有闭包?

  • 1、先来看一段代码
    • 发现没有, 在函数内部想要修改外部的变量是十分容易的一件事. 尤其是全局变量. 这是非常危险的. 试想, 我写了一个函数. 要用到name, 结果被别人写的某个函数给修改掉了. 多难受.
let name = "周杰伦";
function chi(){
    name = "吃掉";
}
chi();
console.log(name);
  • 2、接下来. 我们来看一个案例:
//js01
var name = "xwl"

setTimeout(function(){
    console.log("一号工具人:"+name) 
}, 5000);

//js02
var name = "gmm"
console.log("二号工具人", name);

//HTML
<script src="js01.js"></script>
<script src="js02.js"></script>
- 此时,运行代码,返回的name都是"gmm"
- 很明显,  虽然各自js在编写时是分开的. 但是在运行时, 是在同一个空间内执行的. 他们拥有相同的作用域. 此时的变量势必是非常非常不安全的. 那么如何来解决呢?  注意, 在js里. 变量是有作用域的. 也就是说一个变量的声明和使用是有范围的. 不是无限的. 这一点, 很容易验证.
function fn(){
    let love = "爱呀"
}
fn()
console.log(love)   // Uncaught ReferenceError: love is not defined

比较的真实的案例

  • html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="xwl.js"></script>
    <script src="gmm.js"></script>
    <script>
        // 有人要干活了....
        xwl.aes_encrypt();
        xwl.aes_dencrypt();
        xwl.md5();
        gmm();
    </script>
</head>
<body>

</body>
</html>
  • xwl.js
// 函数在执行的时候. 会产生一个局部作用域.
// 这个局部作用域外界是无法进行修改的.
var xwl = (function(){ // 这个名字是为了产生一个局部作用域.
    // aes加密逻辑
    // 定格创建的东西. 是全局作用域
    var key = "xwl的密码";

    function gongjv(){  //  可以对字符串七十二变
        console.log("我是工具")
    }

    function aes_encrypt(){
        gongjv();
        console.log("xwl的AES加密, 用到秘钥", key);
    }

    function aes_dencrypt(){ //解密
        console.log("xwl的AES解密, 用到秘钥", key);
    }

    // 这里把函数送出去...
    // js是没有多个返回值.
    // return aes_encrypt, aes_dencrypt;

    return {
        aes_encrypt: aes_encrypt,
        aes_dencrypt: aes_dencrypt,
        md5:function(){
            console.log("xwl又来新活了. 赶了一个md5");
        }
    }

})();
  • gmm.js
var gmm = (function(){
    // rsa加密逻辑
    // 定格创建的东西. 是全局作用域
    var key = "gmm的密码";

    function rsa_encrypt(){
        console.log("gmm的RSA加密, 用到秘钥", key);
    }

    // 这里把函数送出去...
    return rsa_encrypt;
})();

总结

  • 至此. 何为闭包? 上面这个就是闭包. 相信你百度一下就会知道. 什么内层函数使用外层函数变量. 什么让一个变量常驻内存.等等. 其实你细看. 它之所以称之为闭包~. 它是一个封闭的环境. 在内部. 自己和自己玩儿. 避免了对该模块内部的冲击和改动. 避免的变量之间的冲突问题.
  • 闭包的特点:
      1. 内层函数对外层函数变量的使用.
      1. 会让变量常驻与内存.