闭包速记

闭包速记

什么是闭包?

谈到闭包,很多人总是会对闭包的概念比较模糊,简单来说如下:

  • 闭包就是能够读取其他函数内部变量的函数
  • 闭包是指有权能够访问另外一个函数作用域中变量的函数 ,创建闭包的最常见方式就是在一个函数内部创建另一个函数,通过另外一个函数访问这个函数的局部变量,利用闭包可以突破作用域链。

闭包的特性如下:

  • 函数内再嵌套函数;
  • 内部函数可以引用外层的参数和变量;
  • 参数和变量不会被垃圾回收机制回收;

谈一下对闭包的理解?

  • 使用闭包主要是为了设计私有化的方法和变量 。闭包的优点可以避免全局变量的污染 ,缺点是闭包会常驻内存,会增大内存的使用量 ,使用不当很容易造成内存泄漏。在js中,函数即闭包,只有函数才会产生作用域的概念。
  • 闭包的最大用处有两个,一个是可以读取函数内部的变量 ,另外一个就是让这些变量始终保存在内存中
  • 闭包的另外一个好处就是封装对象的私有属性和私有方法
  • 使用闭包的好处就是实现封装和缓存 ,坏处就是消耗内存,不正当使用会造成内存溢出问题。

使用闭包注意项:

  • 由于闭包会使得函数中的变量都保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在 IE 中可能会导致内存泄漏。
  • 如何解决呢:就是在退出函数之前,将不使用的变量全部清除

闭包的应用:

闭包在Javascript 中非常常见,它允许函数访问和操作函数外部的变量。最常见的应用之一是创建私有变量和私有方法。

例如:我们可以使用闭包来创建一个计时器:

js 复制代码
/**
 * 闭包实现计时器
 */

function createCounter() {
    let count = 0;

    return {
        increment() {
            count++;
        },
        getCurrentCount() {
            return count;
        }
    }
}

const counter = createCounter();
counter.increment();
console.log(counter.getCurrentCount()); //输出1

上述例子中,createCounter函数返回了一个对象,该对象有两个方法:incrementgetCurrentCount。这两个方法都可以访问和操作createCounter函数内部的私有变量count。由于createCounter函数的执行上下文(包括其变量对象)在返回的对象方法被调用时依然存在,因此这些方法形成了一个闭包,可以访问和操作count

使用闭包造成内存泄漏如何解决:

当闭包引入了一个外部函数的变量,并且这个闭包被长期保存 (例如被赋值给一个全局变量或者被加入到一个长期存在的数据结构中),那么外部函数的执行上下文(包括变量对象)就不能被垃圾收集器回收 ,即使外部函数本身已经不需要了。这种情况可能会导致内存泄漏

js 复制代码
function createLeakyCounter() {
    let count = 0;

    return {
        increment: function () {
            count++;
        }
    }
}

// 将闭包赋值给一个全局变量
window.leakyCounter = createLeakyCounter();

// 假设其他代码在后续的执行过程中不断调用 leakyCounter.increment()

上述例子中,createLeakyCounter函数返回了一个只有increment方法的对象。这个对象被赋值给了全局变量leakyCounter,因此它不会被垃圾收集器回收。而leakyCounter又引用了createLeakyCounter函数内部的变量count,导致createLeakyCounter的执行上下文也不能被回收。即使createLeakyCounter函数本身不再需要,它的执行上下文仍然会占据内存,造成内存泄漏。

解决方法:解决由闭包引起的内存泄漏的一种常见的方法是解除不必要的引用。

在上述例子中我们可以将leakyCounter设为null来解除对createLeakyCounter执行上下文的引用。当没有其他代码再引用leakyCounter时,它的执行上下文就可以被垃圾收集器回收了,从而避免了内存泄漏。

js 复制代码
window.leakyCounter = null;
相关推荐
kyriewen4 分钟前
我同时用了 Claude Code、Cursor 和 Codex,说说三个工具的真实差距——2026 年选错工具比不用 AI 更浪费时间
前端·ai编程·claude
Jackson__30 分钟前
为了拯救我的腰椎和颈椎,我做了款浏览器插件!
前端·javascript·开源
闲猫35 分钟前
Python FastAPI + SQLAlchemy 入门教程:从零搭建你的第一个 Web 应用
前端·python·fastapi
林小帅1 小时前
NestJS v11 + Prisma v7 ESM 迁移配置解析
前端·javascript·后端
IT_陈寒1 小时前
React的setState竟然不是立刻生效的,害我调试半天
前端·人工智能·后端
简简单单就是我_hehe1 小时前
前端埋点日志解决方案:完整 User-Agent 解析工具实现,爬虫识别、设备品牌、操作系统、浏览器版本全解析(附完整源码)
前端·爬虫
William_Xu2 小时前
Vue 2 与 Vue 3 生命周期对比
前端
Hilaku2 小时前
为什么你的大文件断点续传,一遇到弱网就崩溃?
前端·javascript·程序员
众人皆醒我独醉2 小时前
Pod 一直 Terminating,死活删不掉?三个凶手,每一个你都意想不到
面试·kubernetes
胡哈3 小时前
React Compiler:让开发者忘掉 memo 这件事
前端·react.js