# 12.闭包
# 1.变量作用域
变量根据作用于的不同分为两种:全局变量和局部变量
- 函数内部可以使用全局变量
- 函数外部不可以使用局部变量
- 函数执行完毕,本作用域内的局部变量会销毁
# 2.什么是闭包
闭包(closure) 指有权访问另外一个函数作用域中变量的函数 ——JavaScript高级程序设计
一个作用域,可以访问另外一个函数内部的局部变量
function fn() {
let num = 10
function fun() {
console.log(num)
}
fun()
}
fn()
// 如果是,现在要在全局作用域中输出num
function fn() {
let num = 19
return function () {
return num
}
}
let f = fn()
console.log(f())
# 3.闭包的主要作用
延伸了变量的作用范围
# 4.闭包的使用
lis = document.querySeletorAll('li')
for(let i = 0; i < lis.length; i++) {
// 利用for循环创建四个立即执行函数
(function(i) {
// 匿名函数中调用了立即执行函数的i
// 所以立即执行函数是闭包函数
lis[i].onclick = function() {
console.log(i)
}
})(i);
}
// 立即执行函数也称为小闭包,因为立即执行函数里面的任何一个函数都可以使用它这个i变量
定时器中的闭包
for(let i = 0; i < lis.length; i++) {
(function(i){
setTimeout(function(){
console.log(i)
},i*1000)
})(i)
}
计算打车价格
// 问题描述
// 打包起步价13(3公里内),之后每多一公里增加 5块钱。用户输入公里数就可以计算打车价格
// 如果有拥堵情况,总价格多收取10块钱拥堵费
let car = (function(){
let start = 13; // 起步
let total = 0; // 总价
return {
// 正常价格
price:function (journey) {
if(journey <= 3) {
total = start
} else {
total = start + (journey - 3) * 5
}
return total
},
// 拥堵之后的价格
jam: function (flag) {
return flag ? total + 10 : total
}
}
})();
// 因为是立即执行函数,所以car已经获取到了对象中的两个函数
console.log(car.price(5))
console.log(car.jam(true))
let name = 'The Window'
let obj = {
name: 'My obj',
getNameFunc: function() {
return function() {
return this.name
}
}
}
console.log(obj.getNameFunc()())
// The Window
let name = 'The Window'
let obj = {
name: 'My Object',
getNameFunc: function() {
console.log(this)
let that = this
return function() {
return that.name
}
}
}
console.log(obj.getNameFunc()())
// My Objects
# 5.闭包总结
闭包是什么?——闭包是一个函数(一个作用域可以访问另外一个函数的局部变量)
闭包的作用是什么?——延伸变量的作用范围