likes
comments
collection
share

你不知道的JavaScript之闭包

作者站长头像
站长
· 阅读数 24

前言

在初读你不知道的JavaScript这本书时,接触到了闭包这个概念,看了很多遍都没能理解其中的奥秘,直到一位高人用一种方式让我对JavaScript闭包有了更深入的认识。

废话少说,上来就是一个思考题切入主题。

function add() {
    var count = 0;
    function fn() {
        return ++count;
    }
    return fn;
}

var res = add();
console.log(res());
console.log(res());
console.log(res());

这段代码最后会输出什么内容呢?答案如下:

你不知道的JavaScript之闭包 啊???为什么输出的不是三个1?不知道原因😋?且听我慢慢道来。😀

什么是闭包

闭包是指有权访问另外一个函数作用域中的变量的函数。根据函数的作用域,我们知道外部函数无法访问内部函数的变量,而闭包的出现就是为了解决这一问题,使得有权访问函数作用域中的变量

闭包的形成过程

以以上思考题为例:

定义了一个名为 add 的函数,其中:

  1. 在函数内部定义了一个局部变量 count,并将其初始化为 0。

  2. 在函数内部又定义了一个名为 fn 的内部函数,内部函数可以访问外部函数的变量 count。

  3. 内部函数 fn 返回 count 自增后的值。

  4. add 函数返回内部函数 fn。

  5. 执行 var res = add();,将 add 函数的返回值(即内部函数 fn)赋值给变量 res。此时,res 变量就持有了对内部函数 fn 的引用。

  6. 调用 res() 三次: 第一次调用时,count 的值为 1,fn 返回 1。

    第二次调用时,count 的值为 2,fn 返回 2。

    第三次调用时,count 的值为 3,fn 返回 3。

由于 res 持有对 add 内部函数 fn 的引用,并且 fn 中引用了外部函数 add 的变量 count,所以在每次调用 res() 时,都能够访问并修改 count 的值,这就是闭包的形成过程。

闭包的作用

通过上述代码可以总结出闭包所拥有的以下几种作用:

  1. 状态的保持: 内部函数 fn 保留了对外部函数 add 中局部变量 count 的引用,使得 count 的值得以在多次调用 res() 时得以保持和更新,而不会被重置或丢失

  2. 私有变量的实现: 外部函数 add 中的 count 变量对外部是不可见的,只能通过内部函数 fn 来访问和修改,从而实现了一种私有变量的效果,避免了全局污染

  3. 函数的延续执行: 内部函数 fn 被返回后,仍然能够访问外部函数 add 的作用域,因此在 res 被调用时,fn 仍然能够保留对 add 的状态和作用域的引用,使得函数的执行可以延续,并且能够记住之前的状态

  4. 模块化开发: 通过闭包,可以实现模块化开发,将一些变量和函数封装在一个闭包中,外部只暴露必要的接口,从而实现了代码的封装和复用

总结

其实对于闭包的理解,我们可以将它类比为背包,当我们返回会传递一个函数时,就相当于携带了一个背包,其中背包中存储着函数声明时作用域内的所有变量。当函数执行完毕时,传递背包会删除掉没有被内部函数所引用的变量只保留被内部函数引用了的变量。

本篇文章就到此为止啦,希望通过这篇文章能对你理解JS闭包有所帮助,本人水平有限难免会有纰漏,欢迎大家指正。如觉得这篇文章对你有帮助的话,欢迎点赞收藏加关注,感谢支持🌹🌹。

你不知道的JavaScript之闭包

转载自:https://juejin.cn/post/7367997561510101028
评论
请登录