闭包形成的条件:
- 有一个函数A,在A函数内部返回一个B函数
- 在B函数内部,访问A函数私有变量
- 在A函数外部,有一个变量引用返回的B函数
function A(){
let num=100
//A函数内部返回一个B函数
return function B(){
console.log(num) //B函数内部,访问A的私有变量num
}
}
let f=A() //变量f引用返回的B函数
闭包形成后:
- 生成一个不被销毁的函数执行空间
- 内容函数叫做外部的闭包函数
闭包的概念:
有一个A函数,在A函数内部返回一个B函数
在B函数内部,访问A函数内部私有变量在A函数外部,有一个变量引用返回的B函数
有函数嵌套,内层函数被返回
内层函数访问外层函数私有变量
返回的内层函数被引用
闭包三种写法,显示写法,隐示写法,自调用函数
显示写法:
function A(){
let num=100
// A函数内部返回的一个B函数
return function B(){
console.log(num) //函数内部,访问A函数私有变量num
}
}
let f=A()//变量引用返回的B函数
隐式写法:
let B
function A(){
let num=200
B=function(){
console.log(num)
}
}
自调用函数:
let x=(function(){
let num=300
return function B(){
console.log(num)
}
})()
闭包应用:(项目需求,分别给每个明星点赞)
<style>
* {
padding: 0;
margin: 0;
}
ul,
li {
list-style: none;
}
ul {
display: flex;
width: 400px;
margin: 100px;
}
li {
width: 100px;
height: 300px;
border: 1px solid rgb(37, 37, 37);
margin-left: 10px;
}
h2 {
padding-bottom: 200px;
}
</style>
</head>
<body>
<div>
<ul>
<li>
<h2>明星1</h2>
<button>点赞 0</button>
</li>
<li>
<h2>明星2</h2>
<button>点赞 0</button>
</li>
<li>
<h2>明星3</h2>
<button>点赞 0</button>
</li>
</ul>
</div>
<script>
/*
明星点赞
1. 循环遍历按钮绑定事件
2. 定义变量,记录点赞数
*/
const buttonEles = document.querySelectorAll('button')
for (var i = 0; i < buttonEles.length; i++) {
// 1. 函数嵌套
function fun() {
var num = 0 //点赞数量
// 2. 外部引用内层函数
buttonEles[i].onclick = function () {
num++ // 3. 内层函数使用外层函数变量
this.innerHTML = '点赞 ' + num
}
}
fun()
}
// for (var i = 0; i < buttonEles.length; i++) {
// (function(k){
// var num = 0 //点赞数量
// // 2. 外部引用内层函数
// buttonEles[k].onclick = function () {
// num++ // 3. 内层函数使用外层函数变量
// this.innerHTML = '点赞 ' + num
// }
// })(i)
// }
// for (var i = 0; i < buttonEles.length; i++) {
// let num = 0 //点赞数量
// // 2. 外部引用内层函数
// buttonEles[i].onclick = function () {
// num++ // 3. 内层函数使用外层函数变量
// this.innerHTML = '点赞 ' + num
// }
// }
</script>
</body>