闭包

81 阅读1分钟

函数和其它周围的的状态(词法环境)的引用捆绑在一起形成闭包

闭包是可以在另一个作用域,调用一个函数的内部函数并访问到该函数的的作用域中的成员
非闭包情况:当调用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函数执行完毕的时候,内部成员没有被释放,反而被延长了使用

闭包的本质:函数在执行的时候会放到一个执行栈上,当函数执行完毕后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能被释放,因此内部函数依然可以访问外部函数的成员。

闭包的案例:

  1. 函数只执行一次:只支付一次付款
// 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)
  1. 求平方
// 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))
  1. 求工资:基本工资加绩效工资
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))