面试题:讲讲你对闭包的理解?有什么优缺点

面试题:讲讲你对闭包的理解?有什么优缺点?

对闭包的理解

从 JS 作用域链的角度出发,函数外部无法访问到函数中的变量,但函数内部可以访问到其外部的变量。所谓闭包(closure),是一种在函数外部访问函数内部变量的一种方式。通常通过在函数中返回一个新函数的方式实现闭包,这个新函数中可以访问到返回它的函数中的所有执行上下文。

词法作用域:创建闭包时所在的作用域

对于以下示例,A 函数返回了 B 函数,此时 B 函数中可以访问到 A 函数中的所有执行上下文(变量等),将返回的 B 函数赋给一个变量,此时在 A 函数外也可以访问到 A 函数中定义的变量(包括为了得到 B 函数传给 A 函数的参数)。

function A(n){function B(){n++;console.log(`n=${n}`)}return B;
}let x = A(0);
x(); // n=1
x(); // n=1

通过以上示例,我们也可以认为闭包就是能读取其他函数内部变量的函数

闭包的优缺点

优点

  1. 数据封装:闭包可以将数据封装起来,并通过特定接口向外暴露

    function createCounter() {let count = 0; // 封装数据return { // 通过返回的闭包对封装数据进行访问和修改increment: function() {count++;return count;},decrement: function() {count--;return count;},getCount: function() {return count;}};
    }const counter = createCounter();
    console.log(counter.increment()); // 1
    console.log(counter.increment()); // 2
    console.log(counter.getCount()); // 2
    console.log(counter.decrement()); // 1
    
  2. 减少全局变量:闭包可以减少程序中对全局变量的依赖,从而避免命名冲突和全局命名空间的污染

  3. 函数工厂:闭包可以用来创建函数工厂,根据传入的参数,动态生成不同的函数。

    function powerFactory(exp) {return function(base) {return Math.pow(base, exp);};
    }const square = powerFactory(2); // 传入指数为 2,则生成平方函数
    const cube = powerFactory(3); // 传入指数 3,则生成立方函数console.log(square(4)); // 输出 16
    console.log(cube(2)); // 输出 8
    
  4. 惰性计算(一种缓存实现):闭包可以用于惰性计算,即在有需要的时候才计算值,从而提高性能。这也可以理解为缓存的一种实现方式,某些值在第一次访问时计算并缓存,之后访问时直接返回缓存的值。

    function lazyValue(fn) {let cachedValue;return function() {if (cachedValue === undefined) {cachedValue = fn();}return cachedValue;};
    }const getValue = lazyValue(() => {console.log("Computing value...");return 42;
    });console.log(getValue()); // "Computing value..." 42
    console.log(getValue()); // 42
    

缺点

  1. 内存泄漏:闭包会导致被其引用的变量无法被垃圾回收,此时这些内存无法被其他程序所利用,从而易造成内存泄漏。解决方式-1 为:在不需要使用闭包时,手动清理闭包引用(即将指向闭包的变量赋值为 null)。解决方式-2 为使用闭包而不创建闭包

    function createClosure() {var largeArray = new Array(1000000).fill('data');return function() {console.log(largeArray[0]);};
    }var closure = createClosure(); // 由于 largeArray 被闭包引用,所以无法被垃圾回收
    closure = null; // 解除对闭包的引用,允许垃圾回收器回收 largeArraycreateClosure(); // 使用闭包,而不创建闭包
    
  2. 性能问题:因为闭包会持有其词法作用域中的变量,从而会导致这些变量的生命周期变长,从时间的角度来说占用了更多内存。此外,闭包的原理是基于作用域链查找,使用闭包时,JS 引擎需要在多层作用域链中查找变量,从而影响执行效率。每次创建闭包时,都会涉及到内存分配操作。频繁创建和销毁闭包会增加垃圾回收的频率和开销,影响程序整体性能。解决方式:尽量重用闭包,减少闭包的创建次数,减少不必要的作用域嵌套。

  3. 代码复杂性:闭包的使用会增加代码的复杂性,使得代码可读性下降,从而可维护性降低。

REFERENCES

https://www.runoob.com/w3cnote/closure-intro.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt 中QList、QListIterator 、QMutableListIterator、QMap用法

#include <QCoreApplication> #include <QDebug>//QListIterator void printList() {QList<int> list;list<<1<<2<<3<<4<<5;QListIterator<int> i(list);qDebug()<<"正序打印....";//正序打印for(;i.ha…

jsonl - JSON Lines

文章目录 一、关于 JSON Lines1.UTF-8编码2.每一行都是有效的JSON值3.行分隔符为\n 4.建议的惯例 二、示例1、Better than CSV2、Easy Nested Data 三、Json 相关工具应用 一、关于 JSON Lines 官网&#xff1a;https://jsonlines.org &#xff08;下文翻译自此&#xff09;js…

如何利用Web Components提高前端开发效率?

Web Components 是一种用于构建可复用的可扩展组件的技术。它为前端开发提供了一种模块化的方法&#xff0c;可以提高开发效率。下面是一些利用 Web Components 提高前端开发效率的方法&#xff1a; 代码重用&#xff1a;Web Components 可以创建可独立使用的组件&#xff0c;这…

别再emo了,还不赶紧去考PMP,搞钱要紧~

自从疫情之后经济大不如从前&#xff0c;现在大环境都不好&#xff0c;很多公司都在裁员&#xff0c;像我朋友就在上个月被裁掉了&#xff0c;虽说拿了补偿但也不可能靠那点补偿生活的&#xff0c;所以我朋友找了很久的工作&#xff0c;但是由于大环境的缺失所以导致他的薪资直…

搭建 3D 智慧农场可视化

运用图扑自主研发的 HT 产品&#xff0c;全程零代码搭建 3D 轻量化 Low Poly 风格的智慧农场可视化解决方案&#xff0c;无缝融合 2D、3D 技术&#xff0c;1&#xff1a;1 还原农场的区域规划&#xff0c;展开对农作物间的网格化管理。

js控制并发请求的最优解和js控制调用频率,大量请求延迟执行

js控制并发请求的最优解 思路&#xff1a;维护一个运行池&#xff0c;一个等待队列&#xff0c;出一个进一个&#xff0c;控制运行池的大小 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv&q…

深入探讨:Kubernetes 与低代码的原理及应用实战

随着云计算技术的飞速发展&#xff0c;云原生技术逐渐成为企业数字化转型的重要支撑。其中&#xff0c;Kubernetes和低代码作为云原生的两大关键技术&#xff0c;不仅为企业提供了灵活高效的IT解决方案&#xff0c;更助力企业快速响应市场变化&#xff0c;提升竞争力。本文将详…

webSecurity安全

0x01 简介 https://www.electronjs.org/zh/docs/latest/tutorial/security#6-%E4%B8%8D%E8%A6%81%E7%A6%81%E7%94%A8-websecurity 大家好&#xff0c;今天跟大家讨论的是 Electron 的安全配置选项 —— webSecurity 这在之前的文章 《Electron安全与你我息息相关》 中就已经提…

C# 解决 Excel 自动适应列宽的问题

目录 问题现象 原因分析 范例运行环境 解决问题 生成测试文本 实现自适应 小结 问题现象 通过 COM 操作 Excel 自动适应列宽的方法是 AutoFit 方法&#xff0c;该方法适于自动适应列宽或行高。 最近在我们的一款应用里发现效果并没有符合预期&#xff0c;我们提供了一…

【调试笔记-20240604-Linux-为 OpenWrt-23.05 添加自己的 feed 软件包】

调试笔记-系列文章目录 调试笔记-20240604-Linux-为 OpenWrt-23.05 添加自己的 feed 软件包 文章目录 调试笔记-系列文章目录调试笔记-20240604-Linux-为 OpenWrt-23.05 添加自己的 feed 软件包 前言一、调试环境操作系统&#xff1a;Ubuntu 22.04.4 LTS编译环境调试目标 二、…

HTML、HTML5一览

文章目录 HTML简介标签基本标签格式化文本链接图像块级元素列表表格框架表单实体 HTML5 此篇用于优化csdn第一篇文章 HTML 简介 HTML 是用来描述网页的一种语言。 HTML 指的是超文本标记语言: HyperText Markup Language HTML 不是一种编程语言&#xff0c;而是一种标记语言…

数据中心的中台前端风格大屏设计开发

数据中心的中台前端风格大屏设计开发

DevOps全面综述:从概念到实践

一、背景与概述 1.1 DevOps的起源与发展 DevOps&#xff08;Development and Operations的缩写&#xff09;是软件工程领域中的一种文化和实践方法&#xff0c;旨在促进开发团队与运维团队之间的协作&#xff0c;从而实现更高效、更可靠的软件交付。DevOps起源于敏捷软件开发方…

Spring类加载机制揭秘:深度解析“准备”阶段

1. 引言 在Spring框架中&#xff0c;类加载机制是一个至关重要的环节&#xff0c;关系到Spring容器如何动态地加载、解析和管理应用程序中的类。其中&#xff0c;“准备”阶段作为类加载过程中的一个关键步骤&#xff0c;对于理解整个类加载机制具有重要意义。本文将对Spring类…

深入了解 Postman 中的变量

在我们进行 API 开发和测试时&#xff0c;使用诸如 Postman 之类的工具可以极大地简化工作流程&#xff0c;提高效率。Postman 的一个强大功能就是变量&#xff08;Variables&#xff09;。利用变量&#xff0c;我们可以使我们的请求变得更加动态和灵活&#xff0c;避免重复输入…

猫毛过敏的克星!宠物空气净化器,铲屎官的终极武器~

现在很多人都喜欢养猫&#xff0c;但约有10%的人会对猫咪产生过敏反应。常见的症状包括打喷嚏、流鼻涕&#xff0c;严重时甚至会呼吸困难。 过敏源依附在宠物的毛发和皮屑上&#xff0c;通过空气传播&#xff0c;遍布家中的各个角落&#xff0c;如地面、衣物和家具。这不仅增加…

期权和股权有哪些含义?股权和期权有哪些区别?

今天带你了解期权和股权有哪些含义&#xff1f;股权和期权有哪些区别&#xff1f;股权是有限责任公司或股份有限公司股东对公司享有的人身权和财产权的综合权利。期权是指赋予持有者在特定日期或之前以固定价格购买或出售资产的权利的合同。 期权有哪些含义&#xff1f; 期权是…

Echarts 取消鼠标滑动时产生的竖线

文章目录 问题分析问题 当我们在坐标轴中使用多组数据时会产生如下效果,出现两根竖线,不太美观 分析 axisPointer 属性设置为 none(建议使用) 在 ECharts 中,鼠标滑动时产生的竖线是由 tooltip 组件的 axisPointer 属性控制的。要取消这一功能,可以将 tooltip 组件的 …

Java18新特性有哪些

Java 18 于 2022 年 3 月 22 日正式发布&#xff0c;它带来了一些新特性和改进&#xff0c;主要包括以下几点&#xff1a; JEP 400: UTF-8 by Default123&#xff1a;JDK 将 UTF-8 设置为默认字符集&#xff0c;这使得依赖于默认字符集的 API 在所有实现、操作系统、区域设置和…

加入不正确的位置编码会破坏掉原本的信息吗?

会 位置编码的作用 在Transformer中&#xff0c;位置编码的主要作用是让模型感知输入序列中各个词的位置。因为Transformer完全依赖自注意力机制&#xff0c;它本身并没有序列信息&#xff0c;位置编码的引入就是为了补充这一点。 加法操作的合理性 位置编码通过加法操作与…