【前端进阶】一文轻松教你理解透闭包

895 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

前言

经过上一章节的学习,我们要进入下一个篇啦

闭包

闭包的概念

闭包的概念并不复杂,但是它的定义比较绕:

  • 闭包(Closure): 函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。
    • 可以在另一个作用域中调用另一个函数的内部函数并访问到该函数中的作用域中的成员 例子:
    function makeFn () {
        let msg = 'hello world'
        return function () {
            console.log(msg)
        }
    }
    const fn = makeFn()
    fn()
    

闭包的本质

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

来个例子:

函数在执行的时候会放到一个执行栈上当函数执行完毕之后会从执行线上移除

function add () {
    let num = 1
    num = num + 1
    console.log(num)
}
const fn = add

fn() // 2
fn() // 2
fn() // 2

每次我们执行这段代码的时候,num又被重置为1,如此往复

那我们想要代码可以正常累加该怎么办呢?

闭包就来了,闭包堆上的作用域成员因为被外部引用不能释放,因此内部函数依然可以访问外部函数的成员。

function add () {
    let num = 1
    return function () {
        num = num + 1
        console.log(num)
    }
}
const fn = add()

fn() // 2
fn() // 3
fn() // 4

闭包的优缺点

闭包的优点:

  1. 能够读取函数内部的变量
  2. 让这些变量一直存在于内存中,不会在调用结束后,被垃圾回收机制回收 闭包的缺点:

正所谓物极必反,由于闭包会使函数中的变量保存在内存中,内存消耗很大,所以不能滥用闭包。

闭包的案例

求多次方函数

需求

求一个数值的各个次方的值

实现

function makePower (power) {
    return function(number){
        return Math.pow(number,power)
    }
}
// 求平方
let power2 = makePower(2)
// 求立方
let power3 = makePower(3)

// 4的平方
console.log(power2(4)) // 16
// 5的平方
console.log(power2(5)) // 25
// 4的三次方
console.log(power3(4)) // 64

求员工工资

需求:

- 员工工资由绩效工资+基础工资
- 同级别员工基础工资相同

实现

function makeSaleary (base) {
    return function (performace) {
        return base + performace
    }
}
let base1 = makeSaleary(2000)
let base2 = makeSaleary(4000)

console.log(base1(10000)) // 12000
console.log(base1(12000)) // 14000
console.log(base2(10000)) // 14000
console.log(base2(12000)) // 16000

总结

通过本章我们了解了闭包的概念、优缺点、使用,喜欢的同学求关注,求评论,互相加油吧!