闭包
- 全局变量
使用 var 或 let 定义的变量且在函数外部定义的变量称为 全局变量 - 局部变量
在函数内部定义的变量称为 局部变量
// 全局变量
var num = 10;
// 局部变量
functioin f() {
var num2 = 20;
console.log(num); // 10
};
f();
console.log(num2); // 报错 这个变量没有定义
注意:局部变量一般不能再函数外部调用,但可以使用闭包方式调用函数的局部变量
闭包:有权利访问另外一个函数作用域中的变量的函数
// fun是闭包函数 fun2 闭包
function fun() {
var a = 10;
function fun2() {
console.log(a);
};
fun2();
};
fun();
闭包可以延伸变量作用域
function fun() {
var a = 10;
function fun2 () {
console.log(a)
};
return fun2;
};
var f = fun();
f();
问题:局部变量一定不能在函数外部使用?
答:错误的,可以使用闭包来让局部变量可以在外部使用
案例
1 单击 li ,打印每个 li 的序号
<ul class="nav">
<li>北京</li>
<li>上海</li>
<li>深圳</li>
</ul>
var lis = document.querySelector('ul.nav').querySelectorAll('li');
// 思路一:动态添加属性的方式 记住索引
for(var i = 0; i < lis.length; i++) {
lis[i].index = i;
lis[i].onclick = function () {
console.log(this.index);
};
};
// 思路二: 使用闭包方式
for(var i = 0; i < lis.length; i++) {
(function (i) {
lis[i].onclick = function () {
console.log(i);
};
})(i);
};
// 思路三 es6 的语法
for(let i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
console.log(i);
};
};
2 3秒后打印城市
<ul class="nav">
<li>北京</li>
<li>上海</li>
<li>深圳</li>
</ul>
// 使用闭包
for(var i = 0; i < lis.length; i++) {
(function (i) {
seTimieout(function () {
console.log(lis[i].innerHTML);
}, 3000)
})(i);
};
3 滴滴打车 3公里以内 14/公里 ,每增加1公里5元;堵车 在原理收费上多收5元
var c = (function() {
var base = 14;
var sum = 0;
return {
// 堵车
normal: function(n) {
// n 公里数
if (n <= 3) {
sum = base;
} else {
sum = base + (n - 3) * 5;
}
return sum;
},
// 拥挤
yj: function(flag) {
// flag 是否堵车
return flag ? sum + 5 : sum;
}
}
})();
c.normal(5);
console.log(c.yj(true)); // 29