当前位置: 首页 > news >正文

浅浅认识一下js中的闭包

闭包

  • 根据js词法作用域的规则,内部函数总是能访问外部函数中的变量,当通过调用一个外部函数返回的一个内部函数后,即使外部函数执行已经结束了,但是内部函数引用了外部函数中的变量也就需要被保存在内存中,我们把这些变量的集合叫做闭包。

词法作用域

  • 在词法作用域中,变量的作用域由它们在源代码中出现的位置决定,而不是由它们在运行时被引用的位置决定。即一个域所处的环境,是由函数声明的位置来决定的。

闭包的原理

作用域链

  • js引擎在查找变量的时候回先在函数中查找,找不到就会根据outer的指向去到外层作用域中查找,层层往上,这种查找的关系链就称为作用域链 。
  1. 函数在执行前预编译,会创建执行上下文对象。
  2. 变量环境中有一个内定的outer属性用于指明该函数的外层作用域是谁。
  3. outer的指向是根据词法作用域来定的。

变量对象

  • 函数的执行上下文(Execution Context)中包含一个变量对象,它存储了函数的作用域内的所有变量和函数声明。当一个函数形成闭包时,它会保留对其外部执行上下文中的变量对象的引用。

垃圾回收

  • 通常,当一个函数执行完毕,其执行上下文会被销毁(出栈),变量对象也随之消失。但是,如果一个内部函数形成了闭包,那么外部函数的执行上下文将不会被垃圾回收,因为内部函数仍然引用着它的变量对象。

闭包的形成

  • 闭包通常在函数内部定义函数时形成。当内部函数被返回或以某种方式保存下来供以后使用时,它就形成了一个闭包,因为它保持了对其外部作用域中变量的引用,即使外部函数已经完成了执行。

例如:

function foo(){
    var name = 'abc';
    function bar(){
        console.log(count,age);
    }
    var count = 1;
    var age = 18;
    return bar;
}
var age = 20;
const baz = foo();
baz();

bar函数是一个闭包,此时闭包内的变量分别为count=1age=18。即使foo函数已经执行完毕,bar依然能访问到foo函数作用域中的变量。

bar函数内部试图访问countage时,它首先在其直接的作用域中查找,由于bar是在foo的作用域中定义的,所以它能找到countage,并且它们的值分别是1和18。尽管全局作用域中也有一个age变量,但bar函数不会访问到它,因为它首先找到了foo作用域中的age

因此,当执行baz() 时,控制台上将输出118,这是因为bar函数内部的console.log语句打印出了foo作用域中countage的值。

闭包的作用

优点

  1. 封装私有变量:闭包可以用来创建模块化的代码,保护变量不被外部代码访问,同时提供公共接口来与这些变量交互,放置全局变量污染

  2. 数据持久化:闭包可以保持函数执行之间的状态,即使函数在不同时间点被调用,它仍然可以访问上次调用时的变量值。

  3. 延迟执行:闭包可以用于实现异步编程,如定时器和事件处理器,这些场景下闭包可以捕获调用时刻的变量状态。

  4. 回调函数:在异步操作中,闭包经常用作回调函数,以便在异步操作完成后可以访问调用时的作用域中的变量。

缺点

  1. 内存泄漏:闭包可以长时间保留变量,闭包写得越多,闭包占据的调用栈越多,导致调用栈的可用空间就会越小,因为JavaScript的垃圾回收机制不会回收仍然被引用的变量。

  2. 性能考虑:频繁使用闭包可能会影响性能,因为它们增加了内存的负担,并可能使垃圾回收更为复杂。

相关文章:

  • 聊天室Python脚本——ChatGPT,好用
  • 通用信息抽取大模型PP-UIE开源发布,强化零样本学习与长文本抽取能力,全面适配多场景任务
  • Leetcode 378-有序矩阵中第 K 小的元素
  • Linux安装Redis、远程连接Redis
  • Python使用SFTP批量上传和下载一个目录下的所有文件
  • flink tranform算子详解
  • 从厨电模范到数字先锋,看永洪科技如何助力方太集团开启数字新征程
  • 写一个python程序,找出1000以内的质数
  • c++ 接口/多态
  • 【开源免费】基于SpringBoot+Vue.JS疫情管理系统(JAVA毕业设计)
  • Java Web 相关技术概念与知识点
  • [MySQL初阶]MySQL(2)数据类型精讲静态类型和动态类型的对比
  • ubuntu20系统下conda虚拟环境下安装文件存储位置
  • 大模型在呼吸衰竭预测及围手术期方案制定中的应用研究
  • JVM如何判断一个对象可以被回收
  • 自定义wordpress三级导航菜单代码
  • 摄相机标定的基本原理
  • 15天 — 如何解决 Redis 中的热点 key 问题?Redis 集群的实现原理是什么?Redis 中的 Big Key 问题是什么?如何解决?
  • sqli-lab靶场学习(七)——Less23-25(关键字被过滤、二次注入)
  • 1.RabbitMQ简介
  • 天津做网站美工/seo超级外链工具免费
  • 济南网站的优化/深圳百度
  • python 发表wordpress/抖音seo优化软件
  • 服务号不认证可做微网站吗/近期的新闻消息
  • dz论坛网站建设/怎样创建自己的电商平台
  • 怎么给公司做免费网站/网上教育培训机构排名