什么是闭包:
在封闭的作用域中,添加私有数据 想重用变量又想保护这个变量不被篡改的一种机制,是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量.
<body>
<input type="text" placeholder="请输入要查询的学生姓名" id="ip" />
<button id="btnSet">设置成绩</button>
<button id="btnGet">查询成绩</button>
<p id="pInfo">成绩显示区</p>
<!--
存储5个学生的成绩【数学,编程,打游戏】在各自的闭包中
根据姓名查询不同学生的成绩
-->
<script>
function scrore(name) {
/* 闭包内的私有数据 */
const scores = {
chinese: 0,
math: 0,
coding: 0,
};
/*
返回闭包内数据的操作API对象
只要有人访问/引用这个对象
=>score函数无法释放
=>形成闭包
=>每个闭包都可以独立地存储各自的学习成绩
*/
return {
// 设置学习成绩
set(key, value) {
scores[key] = value;
},
// 查询所有
getAll() {
return `${name}:${JSON.stringify(scores)}`;
},
};
}
</script>
<!-- 业务逻辑 -->
<script>
const arr = ["张三疯","尼古拉斯赵四","隔壁老王"]
/*
{
name1:成绩闭包操作api,
name2:成绩闭包操作api
}
*/
const obj = {}
/* 一人一个成绩闭包的操作API */
const scores = arr.forEach(
// {张三疯:张三疯的成绩操作API}
name => obj[name]=scrore(name)
)
// console.log(obj);
/* 设置成绩 */
btnSet.onclick = function(){
// 拿到用户的输入 张三疯:chinese:50
let [name,key,value] = ip.value.split(":")
// 调用name对应的闭包中的set设置该生的科目成绩
obj[name].set(key,value)
}
/* 根据姓名查询学生的全部成绩 */
btnGet.onclick = function(){
const name = ip.value
// 根据名字拿到其成绩闭包的操作API 进而调用getAll
pInfo.innerText = obj[name].getAll()
}
</script>
</body>
闭包有三个特性:
- 函数嵌套函数
- 函数内部可以引用外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
闭包的优点是:
- 变量被保存起来没有被销毁,随时可以被调用
- 只有函数内部的子函数才能读取局部变量,可以避免全局污染
缺点是:
- 如果闭包使用不当,就会导致变量不会被垃圾回收机制回收,造成内存泄露
银行存钱和取钱,查询余额