闭包速记

闭包速记

什么是闭包?

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

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

闭包的特性如下:

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

谈一下对闭包的理解?

  • 使用闭包主要是为了设计私有化的方法和变量 。闭包的优点可以避免全局变量的污染 ,缺点是闭包会常驻内存,会增大内存的使用量 ,使用不当很容易造成内存泄漏。在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函数返回了一个对象,该对象有两个方法:increment和getCurrentCount。这两个方法都可以访问和操作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;
相关推荐
2601_9499506328 分钟前
练题簿在线免费刷题 从资料整理到考前自测
面试·职场和发展·pdf·word·刷题
福兮说2 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
时间的拾荒人2 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
海绵宝宝转agent2 小时前
MySql高频面试八股开源笔记总结
mysql·面试·开源
郑州光合科技余经理2 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6663 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
凤城老人3 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
Dovis(誓平步青云)3 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
lsc_blog4 小时前
远程和居家办公的经历,技术简历上怎么摆
面试·职场和发展·重构·pdf·求职招聘
码艺-Alimjan4 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js