# 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.闭包总结
闭包是什么?——闭包是一个函数(一个作用域可以访问另外一个函数的局部变量)
闭包的作用是什么?——延伸变量的作用范围
