假设有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>