第1章 什么是闭包
- 闭包是一个函数(一个作用域可以访问另外一个函数的局部变量)
<script>
// 闭包(closure)指有权访问另一个函数作用域中变量的函数
// 简单理解就是一个作用域可以访问另外一个函数内部的局部变量
// 如下:我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num 这个就是闭包!
function fn() {
var num =10;
function fun() {
console.log(num);
}
fun();
}
fn();
</script>
第2章 闭包的作用
- 延伸了变量的作用范围
<script>
// 我们fn 外面的作用域可以访问fn 内部的局部变量 return返回
// 闭包的主要作用:延伸了变量的作用范围
function fn() {
var num =10;
// function fun() {
// console.log(num);
// }
// return fun;
return function() {
console.log(num);
}
}
var f = fn();
f();
// 类似于
// var f = function fun() {
// console.log(num);
// }
</script>
第3章 闭包应用
应用(1):onclick事件点击li输出当前的索引号
<body>
<ul class="nav">
<li>榴莲</li>
<li>香蕉</li>
<li>苹果</li>
<li>火龙果</li>
</ul>
<script>
// 1.我们可以利用动态添加属性的方式
var lis = document.querySelector('.nav').querySelectorAll('li');
for(var i = 0; i < lis.length; i++) {
lis[i].index = i;
lis[i].onclick = function() {
console.log(this.index);
}
}
// 2. 利用闭包的方式得到当前小li 的索引号 !!!面试常问的案例!!!
for(var i = 0; i < lis.length; i++) {
// 利用for循环创建了4个立即执行函数,最后一个小括号是调用!(function () {})()
(function(i) {
// console.log(i); 2.1直接依次打印索引号
// 2.2 onclick鼠标点击事件,点击后触发获取索引号
lis[i].onclick = function() {
console.log(i);
}
})(i); //这个i调到形参上去,然后依次打印结果会是 0123 立即执行函数
}
</script>
</body>
思路:
应用(2): 定时器中的闭包
<body>
<ul class="nav">
<li>榴莲</li>
<li>香蕉</li>
<li>苹果</li>
<li>火龙果</li>
</ul>
<script>
// 闭包应用-3秒钟之后,打印所有li元素的内容
// 获取元素
var lis =document.querySelector('.nav').querySelectorAll('li');
// ()() 立即执行函数
for(var i =0; i < lis.length; i++) {
// 利用立即执行函数里面小闭包 只要是在立即执行函数里面的任何一个函数,都可以使用立即执行函数这个i变量,这就是闭包的一个运用
// 3秒过后打印 innerHTML内容
(function (i) {
setTimeout(function() {
console.log(lis[i].innerHTML);
}, 3000)
})(i)
}
</script>
</body>
应用(3): 打车价格中的闭包
<script>
// 闭包应用-计算打车价格
// 打车起步价13(3公里内),之后每多一公里增加5元钱,用户输入公里数就可以计算打车价格
// 如果有拥堵情况,总价格多收取10块钱拥堵费
// function fn() {};
// fn();
// 1.以下这个写法就不需要像上面这个fn()这样调用了,比较麻烦
// 2.立即执行函数 不需要调用直接执行
(function() {
var start = 13; // 起步价 局部变量
var total = 0; // 总价 局部变量
return {
// 正常的总价
price: function(n) {
if (n <= 3) {
total = start;
} else {
total = start + (n - 3) * 5
}
return tatal;
},
// 拥堵之后的费用
yd: function(flag) {
return flag ? total + 10 : total;
}
}
})();
console.log(car.price(5)); // 23
// 拥堵情况下
console.log(car.yd(true)); // 33
console.log(car.price(1)); // 13
</script>
总结
- 一个作用域可以访问另一个函数内部的局部变量,此时产生闭包,这就是闭包
- 在合适的场景使用闭包