什么是闭包
- 闭包(closure)是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰,即形成一个不销毁的栈环境。
- 闭包的特性:
- 函数嵌套函数
- 内部函数可以访问外部函数的变量
- 参数和变量不会被回收。
为什么要有闭包?
- 1、先来看一段代码
- 发现没有, 在函数内部想要修改外部的变量是十分容易的一件事. 尤其是全局变量. 这是非常危险的. 试想, 我写了一个函数. 要用到name, 结果被别人写的某个函数给修改掉了. 多难受.
let name = "周杰伦";
function chi(){
name = "吃掉";
}
chi();
console.log(name);
//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
比较的真实的案例
<!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>
// 函数在执行的时候. 会产生一个局部作用域.
// 这个局部作用域外界是无法进行修改的.
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");
}
}
})();
var gmm = (function(){
// rsa加密逻辑
// 定格创建的东西. 是全局作用域
var key = "gmm的密码";
function rsa_encrypt(){
console.log("gmm的RSA加密, 用到秘钥", key);
}
// 这里把函数送出去...
return rsa_encrypt;
})();
总结
- 至此. 何为闭包? 上面这个就是闭包. 相信你百度一下就会知道. 什么内层函数使用外层函数变量. 什么让一个变量常驻内存.等等. 其实你细看. 它之所以称之为闭包~. 它是一个封闭的环境. 在内部. 自己和自己玩儿. 避免了对该模块内部的冲击和改动. 避免的变量之间的冲突问题.
- 闭包的特点:
-
- 内层函数对外层函数变量的使用.
-
- 会让变量常驻与内存.