前端面试常考 | js闭包

news2024/11/29 2:33:53

文章目录

  • 一. 闭包
      • 1. 介绍闭包
      • 2. 闭包的作用
      • 3. 闭包与变量
  • 二. 闭包引起的内存泄漏
      • 1. 闭包是如何引起内存泄漏的
      • 2. 如何解决闭包引起的内存泄漏
  • 三. 最后


一. 闭包

1. 介绍闭包

有不少开发人员总是搞不清楚匿名函数与闭包两个概念,因此经常混用。同时闭包也是我们前端面试中的高频考点。闭包是指有权访问另一个函数作用域中变量的函数,而创建闭包的常见形式就是在一个函数的内部创建另一个函数如下所示:

function outer(){
	const a =1
	function fn(){
		console.log(a)
	}
}

在浏览器控制台查看发现是存在闭包的
在这里插入图片描述

2. 闭包的作用

闭包其实是一种很常见的设计,比如在我们的节流防抖函数,以及我们的Vue框架,React,都大量的使用了闭包。
首先要介绍的是闭包对作用域变量的保护,也就是实现数据的私有
列如我们要设计一个函数调用次数的函数,不使用闭包设计如下:

let i = 0;
function fun() {
  i++
  console.log(`函数调用了${i}`);
}

但是这种方式被定义的计算变量i容易被修改。
这时如果使用闭包的方式进行设计:

function count() {
     let i = 0;
     function fun() {
         i++
         console.log(`函数调用了${i}`);
     }
    return fun
}
const fn = count()
fn()

这样做我们外部的代码就无法修改在函数作用域中的变量 i
除了上面介绍到的,闭包还可以实现方法的私有化柯里化函数匿名自执行函数等等许多作用,感兴趣的读者朋友可以查阅相关文章。

3. 闭包与变量

作用域链这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。下面这个例子可以清晰的说明这个问题:
本意是每个函数都保存1到10的索引,但是其实所有储存在数组中的函数保存的索引都是10,因为每个函数作用域链中都保存着fn函数的活动对象,所以他们引用的都是同一个变量i。

function fn() {
    var result = new Array();
    for (var i = 1; i < 10; i++) {
         	result[i] = function () {
              return i;
         	}
      }
            return result;
}
array = fn();
console.log(array[1]()); // 10
console.log(array[2]()); // 10

那么怎么解决这个问题呢?我们可以通过创建另一个匿名函数强制让闭包的行为符合预期,如下所示:

function fn() {
    var result = new Array();
     for (var i = 1; i < 10; i++) {
            result[i] = function (num) {
                return function () {
                    return num;
                };
            }(i);
        }
     return result;
}
array = fn();
console.log(array[1]()); // 1
console.log(array[2]()); // 12

二. 闭包引起的内存泄漏

1. 闭包是如何引起内存泄漏的

提到闭包内存泄漏这个点,这是一直存在歧义的一个点,难道闭包就一定会造成内存泄漏吗?那么怎么解决这个内存泄漏呢?
其实不是使用了闭包就会造成内存泄漏的问题,具体的例子可以看上面的案例,那么关于闭包造成内存泄漏是怎么一回事呢?下面我们可以借助于垃圾回收机制的标记清除法可以看出:

function fn() {
     let count = 1;
     function fun() {
          count++
          console.log(`函数调用了${count}`);
      }
     return fun
}
const result = fn()
result() // 2
result() // 3

result是一个全局变量,代码执行完毕不会立即销毁,而result使用fn函数,fn用到fun函数,fun函数里面用到count,cout被引用就不会被回收,所以一直存在。此时闭包就引起了内存泄漏
但是,并不是所有的内存泄漏都需要进行手动回收的,比如React!里面很多闭包不能回收的

2. 如何解决闭包引起的内存泄漏

如果有些变量的应用的内存过大,同时还造成了内存泄漏,那么这时我们就可以考虑解决这个内存泄漏的问题,那么该如何解决呢?

// 这段代码会导致内存泄露
window.onload = function(){
      var el = document.getElementById("id");
      el.onclick = function(){
          alert(el.id);
        }
    }
// 解决方法为
window.onload = function(){
      var el = document.getElementById("id");
      var id = el.id;                                      //解除循环引用
      el.onclick = function(){
           alert(id); 
        }
        el = null;                                          // 将闭包引用的外部函数中活动对象清除即可
    }

三. 最后

关于闭包的的一些琐碎的知识就介绍到这里吧,有疑问的读者朋友可以在评论区提出,关于闭包的更多知识,各位小伙伴可以自行查阅相关文章或者参考《Javascript高级程序设计》中的闭包篇,感觉讲的还是很详细的,感觉又水了一篇文章 (눈_눈)。

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

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

相关文章

我见过最好的天线基础知识

天线作为无线电的发射和接收设备是影响信号强度和质量的重要设备,其在移动通信领域的重要性非常关键。通过对天线选型,天 线安装,天线调整从而保障基站覆盖区域的信号强度与质量。对其的 掌握程度是网规与网优工程师的技能基本要求之一。下文重点说明天线要掌握哪些方面及其原理…

版本控制 | 如何将 UnrealGameSync 与 Perforce Helix Core 结合使用

为了帮助虚幻引擎4和虚幻引擎5的开发&#xff0c;Epic公司开发了UnrealGameSync&#xff0c;使其与版本控制工具Perforce Helix Core交互。虽然UnrealGameSync除了P4V (Helix Core客户端)之外还有许多功能&#xff0c;但主要用途是分发内部引擎和项目构建&#xff0c;它极大地简…

springboot+vue

一、案例结构 用springboot做后端接口&#xff0c;采用restful风格。用vue-cli来创建前端项目&#xff0c;通过axios进行前后端交互。来实现用户的增删改查操作。二、效果图 点击修改&#xff1a; 点击添加&#xff1a; 三、服务器端 控制层代码&#xff1a; package com.ex…

【Tryhackme】dogcat(LFI+文件解析漏洞,Docker逃逸)

免责声明 本文渗透的主机经过合法授权。本文使用的工具和方法仅限学习交流使用&#xff0c;请不要将文中使用的工具和渗透思路用于任何非法用途&#xff0c;对此产生的一切后果&#xff0c;本人不承担任何责任&#xff0c;也不对造成的任何误用或损害负责。 服务发现 ┌──(r…

CentOS7.4安装教程

CentOS7.4安装教程&#xff1a; centos系统自行网上查找链接下载&#xff0c;我使用的是最小安装版本&#xff0c;搞服务器用 1、进入操作系统&#xff0c;选择第一项进行安装&#xff1a; 2、耐心等待&#xff0c;直到弹出这个界面&#xff1a; 3、下拉选择中文&#xf…

磷脂-荧光素标记DSPE-FITC磷脂改性荧光素

磷脂-荧光素标记DSPE-FITC磷脂改性荧光素 中文名称&#xff1a;荧光素标记二硬脂酰磷脂酰乙醇胺 中文别称&#xff1a;磷脂-荧光素标记&#xff1b;二硬脂酰磷脂酰乙醇胺改性荧光素 英文名称&#xff1a;18:0 PE Fluorescein 英文别称&#xff1a;DSPE-FITC 外观&#xff1a…

开发人员的绝佳生产力工具

介绍 从长远来看&#xff0c;每天工作 8 小时对您没有帮助&#xff0c;但利用这些来最大化产出肯定会让您受益。这就是为什么生产力是最重要的事情之一。 今天&#xff0c;我们将学习一些很棒的工具&#xff0c;它们可以提高您的工作效率。除非并且直到您将这些工具集成到您的…

【Lilishop商城】No3-7.模块详细设计,订单模块-1(购物车、收银台)的详细设计

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑&#xff0c;其中重点包括接口类、业务类&#xff0c;具体的结合源代…

【TECH SCIENCE PRESS出版社】2区SCI,仅3个月左右录用,数字孪生、绿色技术、供应链、人工智能物联网、智能传感器相关领域均可

【出版社】TECH SCIENCE PRESS 【期刊简介】IF&#xff1a;3.5-4.0&#xff0c;JCR2区&#xff0c;中科院3区 【检索情况】SCI&EI双检&#xff0c;正刊 【参考周期】3个月左右 【征稿领域】 ①数字孪生在智能医疗系统中的应用&#xff08;2023.3.25截稿&#xff09; …

NetInside助力IT提高业务性能管理能力(一)

需求简介 某外高桥公司的OA系统是其重要的业务系统&#xff0c;OA系统负责人表示&#xff0c;部分用户反馈&#xff0c;访问OA系统时比较慢。需要通过分析系统看一下实际情况。 信息部已对企业领导定义了独立的组&#xff0c;本次要主动分析领导们的使用体验快慢。如果OA系统…

一个带详细程序和注释的实例,手把手带你学会用BP神经网络做预测

目录 1.问题描述 1.1问题剖析 2.实现程序 2.1运行结果 2.3总结 3.预测 3.1输出结果 4.预测理解 1.问题描述 某运输系统连续9年货运量的有关数据如表2-10所示。根据对关于货运量影响因素的分析&#xff0c;这里分别取国内生产总值GDP、工业总产值、铁路运输线路长度、复线…

使用vue-easytable实现仿excel表格,支持可编辑、添加删除行、虚拟表格等功能

使用npm安装vue-easytable npm install --save vue-easytable 在 main.js 中写入以下内容&#xff1a; // 引入样式 import "vue-easytable/libs/theme-default/index.css"; // 引入组件库 import VueEasytable from "vue-easytable"; Vue.use(VueEasyt…

ADI Blackfin DSP处理器-BF533的开发详解49:图像处理专题-Bright (图像亮暗处理)(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 功能介绍 代码实现了图像亮暗处理&#xff0c;代码运行时&#xff0c;会通过文件系统打开工程文件根目下" …/ImageView"路径中的 tes…

[附源码]Node.js计算机毕业设计电子市场计算机配件报价系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

聚焦人机交互智能应用领域,APISIX 在希沃网关的应用与实践

分享嘉宾简海清&#xff0c;视源股份运维负责人。 视源股份&#xff08;CVTE&#xff09;自成立以来&#xff0c;依托在音视频技术、人机交互、应用开发、系统集成等电子产品领域的软硬件技术积累&#xff0c;建立了教育数字化工具及服务提供商希沃&#xff08;seewo&#xff0…

三、JavaScript——编写位置

1.在script标签内编写 JS的代码一般可以写到script标签中&#xff0c;script标签的完整写法是要加type"text/javascript",但这个一般可以省略&#xff0c;所以只用<script>即可 <!DOCTYPE html> <html lang"en"> <head><meta …

【架构师李肯】带你走进架构师的一天

作者简介 *架构师李肯&#xff08;全网同名&#xff09;**&#xff0c;一个专注于嵌入式IoT领域的架构师。有着近10年的嵌入式一线开发经验&#xff0c;深耕IoT领域多年&#xff0c;熟知IoT领域的业务发展&#xff0c;深度掌握IoT领域的相关技术栈&#xff0c;包括但不限于主流…

js逆向之加密方法远程调用

js逆向之加密方法远程调用 加密方法的远程调用主要是使用了RPC协议,RPC(Remote Procedure Call)是远程调用的意思。RPC的应用十分广泛,比如在分布式中的进程间通信、微服务中的节点通信。 我们这里使用的rpc其实是实现两个不同进程通信的一种方式,比如在浏览器执行一些方…

SystemUI 调整Recents中全部清除按钮位置

Recents 即多任务界面&#xff0c;显示最近使用过的APP List的。下面内容都是基于Android 11平台修改的。Android 11上&#xff0c;Recents 这一部分代码其实都已经被挪到Launcher3中。由于个人习惯&#xff0c;所以将内容分类作为SystemUI部分记录。 多任务界面主要几个文件&…

工欲善其事,必先利其器,推荐5款效率神器

有句老话这样讲&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;好的工具可以让你工作起来事半功倍。 1.全能翻译神器——智能翻译官 这是一款超级强大的翻译软件&#xff0c;什么文本、图片、文档&#xff0c;视频、音频&#xff0c;统统都可以翻&#xff0c;像我…