一文搞懂 js闭包

假设有A和B这2个人,现在他们各自被分配了一个任务,A需要完成反爬的数据加密功能,B需要完成用户密码保护加密功能,最终这2个功能都要被应用到公司网站的一个页面上。

var key = "123456"
function fn(){
  console.log("A写的加密逻辑,使用的密钥是:", key)
}
var key = "abcdef"
function fn(){
    console.log("B写的加密逻辑,使用的密钥是:", key)
}

很明显,如果把这两个功能汇总到一个环境下去跑,势必会产生冲突。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="A.js"></script>
    <script src="B.js"></script>
    <script>
        fn();
    </script>
  
</head>
<body>
一个页面
</body>


</html>

为了防止产生冲突,我们就需要尽量将他们开发的这两个功能分开。

很简单,A在所有代码后面加上A,B在所有代码后面加上B。

key_A = "123456"


def fun_A():
    print("A写的加密逻辑,使用的密钥是:", key)
key_B = "abcdef"


def fun_B():
    print("B写的加密逻辑,使用的密钥是:", key)

但是这样你会发现,为了使这个变量名不冲突,你可能会对这个变量名做一个超级长的设计...

很显然,上面那个方案很蠢,那么如何优雅地解决这个问题?

现在先来分析他们会冲突的原因:处于同一个作用域下(全局变量)

那就想办法把这个全局变量变成局部变量 => A写的所有代码全部括在局部里边,B也一样。所以需要封装在一个函数内部

function() {
    var key = "123456"

    function fn() {
        console.log("A写的加密逻辑,使用的密钥是:", key)
    }
}
function() {
    var key = "abcdef"

    function fn() {
        console.log("B写的加密逻辑,使用的密钥是:", key)
    }
}

那怎么产生这个局部空间,得让这个函数运行吧!

那这样就又会出现函数名设计的问题!

思考一下,这个function()函数存在的意义是什么?

function这个函数不是为了让别人调用的,纯粹是为了创建出一个局部空间,那么这个函数名就无所谓了。所以就需要把这个函数定义成立即执行函数(自运行)。 => 赶紧跑出来,得到一个自己的作用域。

(function() {
    var key = "123456"
  
    function fn() {
        console.log("A写的加密逻辑,使用的密钥是:", key)
    }
})()

那现在外界要如何使用呢?

var A = (function() {
  var key = "123456"

  function fn() {
      console.log("A写的加密逻辑,使用的密钥是:", key)
  }
  return fn;
})()
var B = (function() {
  var key = "abcdef"

  function fn() {
      console.log("B写的加密逻辑,使用的密钥是:", key)
  }
  return fn;
})()

现在需要注意的只有 var 声明的变量不能冲突

这就是闭包。闭:局部作用域,包:在这个局部中封装的各种功能,目的:保护你的变量。

现在领导要求A去扩展功能,然后A就又开发了4个加密功能(base64/rsa/aes/md5)。

var A = (function () {
    var key = "123456";

    function fn() {
        console.log("这个函数是这个闭包内部公用的一个计算逻辑")
    }

    function base64() {
        fn()
    }

    function rsa() {
        fn()
    }

    function aes() {
        fn()
    }

    return {  // 返回一个对象
        base64: base64,
        rsa: rsa,
        aes: aes,
        md5: function (s) {
            return "s的md5值"
        },
    }
})(); // 在此处调用函数以创建 A 对象

整合测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="A.js"></script>
    <script src="B.js"></script>
    <script>
        A.base64();
        A.rsa();
        A.aes();
        console.log(A.md5("666"))

        B();
    </script>
  
</head>
<body>
一个页面
</body>


</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nhcjttt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值