前端面试题29(js闭包和主要用途)
JavaScript 中的闭包是一个非常强大的特性,它允许一个函数访问并操作其词法作用域之外的变量。闭包的形成主要依赖于函数的作用域链,即函数可以访问在其外部定义的变量,即使外部函数已经执行完毕。下面我会通过几个方面来帮助你理解闭包的概念:
闭包的定义
闭包是一个函数及其相关的引用环境组合,这个环境包含了该函数在声明时能够访问的所有局部变量、参数和内嵌函数。当一个函数返回后,通常它的局部变量会被销毁,但由于闭包的存在,这些变量将继续存在于内存中,直到没有任何引用指向它们为止。
闭包的形成
闭包通常在函数嵌套的情况下形成。当一个内层函数引用了外层函数的变量时,即使外层函数已经执行完毕,内层函数仍然能够访问这些变量,这就形成了一个闭包。
闭包的例子
function outerFunction() {var outerVariable = 'I am outside!';function innerFunction() {console.log(outerVariable);}return innerFunction;
}var myFunction = outerFunction();
myFunction(); // 输出: I am outside!
在这个例子中,innerFunction
是一个闭包,因为它能够访问 outerFunction
中定义的 outerVariable
,即使 outerFunction
已经执行完毕。
闭包的用途
- 封装私有变量:闭包可以用来隐藏变量,使其不能被外部代码直接访问。
- 持久存储:闭包可以让变量在函数执行后仍然存在,这在实现如计数器、缓存等功能时很有用。
- 事件处理:在事件监听器中,闭包可以记住函数被绑定时的上下文。
- 异步编程:在处理异步操作时,闭包可以确保回调函数能够访问到必要的变量状态。
闭包的潜在问题
- 内存泄漏:如果闭包不当使用,可能导致不必要的变量长期占据内存,从而引起内存泄漏。
- 性能开销:由于闭包需要维护额外的引用,这可能会带来一定的性能开销。
如何避免闭包的副作用
为了减少闭包带来的内存问题,可以确保不再需要的变量及时解除引用,或者在函数结束时显式地将其设置为 null
。
主要用途
-
封装私有变量和方法:
闭包提供了一种创建私有变量的方式,这是JavaScript中实现模块模式的基础。通过闭包,可以将变量和函数的访问权限限制在函数内部,防止全局作用域污染和命名冲突。例如:var counterModule = (function () {var privateCounter = 0;function changeBy(val) {privateCounter += val;}return {increment: function () { changeBy(1); },decrement: function () { changeBy(-1); },value: function () { return privateCounter; }}; })();
-
保持函数状态:
闭包允许函数记住和访问其创建时的环境。这意味着即使函数在后续调用之间,也能保持对某些变量的引用,这些变量的状态可以在多次调用中持续。例如,在事件处理函数中保存当前的状态:for (var i = 0; i < 10; i++) {document.getElementById('button' + i).addEventListener('click', (function (i) {return function () {console.log(i);};})(i)); }
-
实现数据持久性:
闭包可以用来创建具有持久性的数据结构,比如计数器、定时器或是缓存机制。这是因为闭包可以保留对变量的引用,即使在函数执行完成后,这些变量也不会被垃圾回收。 -
异步编程:
在处理异步操作时,如AJAX请求、setTimeout或Promise链中,闭包可以确保回调函数能够访问到正确的变量值和上下文。 -
模块化和代码组织:
利用闭包可以构建模块化的代码结构,将相关功能封装在一起,同时保持其独立性和可重用性。这有助于代码的组织和维护。 -
函数柯里化(Currying)和偏应用(Partial Application):
闭包可以用来创建柯里化函数,这是一种将多参数函数转换为一系列单参数函数的技术。偏应用则是预填充函数的部分参数,返回一个新的函数等待剩余参数。 -
事件监听器和回调函数:
在事件驱动的编程中,闭包经常用于确保事件处理器能够访问事件发生时的正确上下文和数据。
闭包的这些用途展示了它在JavaScript中无处不在的重要性,从简单的计数器到复杂的模块化设计模式,闭包都扮演着关键的角色。然而,不当的使用也可能导致内存泄漏和性能问题,因此理解和正确使用闭包是非常重要的。
相关文章:

前端面试题29(js闭包和主要用途)
JavaScript 中的闭包是一个非常强大的特性,它允许一个函数访问并操作其词法作用域之外的变量。闭包的形成主要依赖于函数的作用域链,即函数可以访问在其外部定义的变量,即使外部函数已经执行完毕。下面我会通过几个方面来帮助你理解闭包的概念…...

使用Keil 点亮LED灯 F103ZET6
1.新建项目 不截图了 2.startup_stm32f10x_hd.s Keil\Packs\Keil\STM32F1xx_DFP\2.2.0\Device\Source\ARM 搜索startup_stm32f10x_hd.s 复制到项目路径,双击Source Group 1 3.项目文件夹新建stm32f10x.h, 新建文件main.c #include "stm32f10x…...
流批一体计算引擎-12-[Flink]旁路输出getSideOutput(OutputTag)实现拆分流和复制流
官网旁路输出 Flink拆分流和复制流 我们在处理数据的时候,有时候想对不同情况的数据进行不同的处理,那么就需要把流进行拆分或者复制。 如果是使用filter来进行拆分,也能满足我们的需求,但每次筛选都要保留整个流,然后遍历整个流,显然很浪费性能,假如能够在一个流了多次…...
【Scrapy】 Scrapy 爬虫框架
准我快乐地重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 再去做没流着情泪的伊人 假装再有从前演过的戏份 重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 你纵是未明白仍夜深一人 穿起你那无言毛衣当跟你接近 🎵 陈慧娴《傻女》 Scrapy 是…...

【笔记】太久不用redis忘记怎么后台登陆了
!首先启动虚拟机linux的centos7 2.启动finalshell 我的redis启动在根目录用 redis-server redis.conf --启动 systemctl status redis --查看redis状态 是否active redis-cli -h centos的ip地址 -p 你要用的redis端口号(默认为6379) -a 你…...

昇思25天打卡营-mindspore-ML- Day14-VisionTransformer图像分类
今天学习了Vision Transformer图像分类,这是一种基于Transformer模型的图像分类方法,它不依赖卷积操作,而是通过自注意力机制捕捉图像块之间的空间关系,从而实现图像分类。 基本原理: 图像分块: 将原始图像划分为多个…...
微信环境内H5网页,用开放标签wx-open-launch-app打开app
一、微信公众号后台配置安全域名 准备一个认证通过的公众号,打开公众号后台 1、设置与开发 2、公众号设置 3、功能设置 4、配置js接口安全域名 二、微信开放平台,将公众号与APP关联 打开微信开放平台后台 1、管理中心 2、公众号 3、选择一个需要操作…...

【c++基础】高精度数不进位加法
高精度数不进位加法 谈及数字即可想到运算,那么高精度数怎么运算呢?今天来系统介绍一下高精度数的加法。 思考一下加法运算,我们可以简单将加法运算这样区分: 有无进位。位数是否相同。 这篇文章我们就来讨论一下无进位的高精度…...
UniApp 中 Web/H5 正确使用反向代理解决跨域问题
因为 Vue3 的构建工具是 Vite,所以配置 vue.config.js 是没用的(Vue2 因为使用 webpack 所以才用这个文件) 这里提供一份 vue.config.js 的示例: module.exports {devServer: {proxy: {/api: {target: http://example.com,chan…...
Redis Stream:实时数据流的处理与存储
Redis Stream:实时数据流的处理与存储 引言 在当今数据驱动的世界中,实时数据处理和存储成为了许多应用的核心需求。Redis Stream作为一种新兴的数据结构,为Redis带来了强大的流处理能力。本文将深入探讨Redis Stream的特点、使用场景以及如何高效地利用它来处理实时数据流…...

【论文阅读】-- Visual Traffic Jam Analysis Based on Trajectory Data
基于轨迹数据的可视化交通拥堵分析 摘要1 引言2 相关工作2.1 交通事件检测2.2 交通可视化2.3 传播图可视化 3 概述3.1 设计要求3.2 输入数据说明3.3 交通拥堵数据模型3.4 工作流程 4 预处理4.1 路网处理4.2 GPS数据清理4.3 地图匹配4.4 道路速度计算4.5 交通拥堵检测4.6 传播图…...
修改编译依赖openssl的libcrypto.so
由于centos7默认使用openssl1.0.2k的libcrypto.so.10共享库。即使openssl升级为3.0.11后,编译使用ldd命令查看共享库依旧会引用libcrypto.so.10。 现希望引用libcrypto.so.3,需要在生成动态链接库的CMakeLists.txt中增加如下配置,明确指定ope…...

����: �Ҳ��������������� javafx.fxml ԭ��: java.lang.ClassNotFoundException解决方法
如果你出现了这个问题,恭喜你,你应该会花很多时间去找解决方法。别问我怎么知道的... 解决方法: 出现乱码的原因:配置vm时 这些配置看似由有空格,换行,实则没有。所以解决办法就是,重新配置你…...

【C++】———— 继承
作者主页: 作者主页 本篇博客专栏:C 创作时间 :2024年7月5日 一、什么是继承? 继承的概念 定义: 继承机制就是面向对象设计中使代码可以复用的重要手段,它允许在程序员保持原有类特性的基础上进行扩展…...
Python人生重开器
Life reopens stimulator """ 作者:->yjy 所有的惊艳都曾历经平庸 """ import random import sys import time# 打印初始界面 print(------------------------------) print(| |) print(| >>人生重…...
python 高级技巧 0708
python 33个高级用法技巧 使用装饰器计时函数 装饰器是一种允许在一个函数或方法调用前后运行额外代码的结构。 import timedef timer(func):"""装饰器函数,用于计算函数执行时间并打印。参数:func (function): 被装饰的函数返回:function: 包装后…...
HOW - React Router v6.x Feature 实践(react-router-dom)
目录 基本特性ranked routes matchingactive linksNavLinkuseMatch relative links1. 相对路径的使用2. 嵌套路由的增强行为3. 优势和注意事项4. . 和 ..5. 总结 data loadingloading or changing data and redirectpending navigation uiskeleton ui with suspensedata mutati…...
`padding`、`border`、`width`、`height` 和 `display` 这些 CSS 属性的作用
盒模型中的属性 padding(内边距) padding 用于控制元素内容与边框之间的空间,可以为元素的每个边(上、右、下、左)分别设置内边距。内边距的单位可以是像素(px)、百分比(%…...
C++ QT 全局信号的实现
每次做全局信号都需要重新建立文件,太麻烦了,记录一下,以后直接复制。 头文件 globalSignalEmitter.h #pragma once //#ifndef GLOBALSIGNALEITTER_H //#define GLOBALSIGNALEITTER_H#include <QObject>class GlobalSignalEmitter : …...

十款绚丽的前端 CSS 菜单导航动画
CSS汉堡菜单是一种非常流行的PC端和移动端web菜单风格,特别是移动端,这种风格的菜单应用更为广泛。这款菜单便非常适合在手机App上使用,它的特点是当顶部菜单弹出时,页面内容将会配合菜单出现适当的联动,让整个页面变得…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...