函数和其它周围的的状态(词法环境)的引用捆绑在一起形成闭包
闭包是可以在另一个作用域,调用一个函数的内部函数并访问到该函数的的作用域中的成员
非闭包情况:当调用makePower函数完毕的时候,其内部变量msg将被释放
function makePower () {
let msg = '123456'
}
const fn = makePower()
fn()
闭包:由于makePower函数返回一个函数,且返回的函数,会调用内部的变量,则内部的变量不会被释放
function makePower () {
let msg = '123456'
return function(){
console.log(msg)
}
}
const fn = makePower()
fn()
闭包的作用:当调用makePower函数执行完毕的时候,内部成员没有被释放,反而被延长了使用
闭包的本质:函数在执行的时候会放到一个执行栈上,当函数执行完毕后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能被释放,因此内部函数依然可以访问外部函数的成员。
闭包的案例:
- 函数只执行一次:只支付一次付款
// once
function once (fn) {
let done = false
return function () {
if (!done) {
done = true
return fn.apply(this, arguments)
}
}
}
let pay = once(function (money) {
console.log(`支付: ${money} RMB`)
})
//只会支付一次
pay(5)
pay(5)
- 求平方
// Math.pow(4, 2)
// Math.pow(5, 2)
function makePower (power) {
return function (number) {
return Math.pow(number, power)
}
}
// 求平方
let power2 = makePower(2)
let power3 = makePower(3)
console.log(power2(4))
console.log(power2(5))
console.log(power3(4))
- 求工资:基本工资加绩效工资
function makeSalary (base) {
return function (performance) {
return base + performance
}
}
let salaryLevel1 = makeSalary(12000)
let salaryLevel2 = makeSalary(15000)
console.log(salaryLevel1(2000))
console.log(salaryLevel2(3000))