手把手教你学会闭包

2023-05-16

前言

MDN对闭包的解释是这样的:一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。MDN文档

解释有点抽象,不好理解,现在我们用代码的形式来解释下。

一. 闭包概念解析

闭包让你可以在一个内层函数中访问到其外层函数的作用域

(1) 父对象的所有变量,对子对象都是可见的,子对象对父对象是不可见的

// 普通函数 
  var a =1
  function f1() {
	a =2 ;
	var b = 3;
   }
   console.log(b)

在f1函数里面是可以访问到函数外部变量a,但是在函数f1外部是访问不到函数内部的变量a的

(2)判断一个函数是不是闭包

f2(a) {
	console.log(a,b)
}
function f1() {
	var a = 1;
	f2(a)
}
f1()

在上述代码中内部函数f2是不能访问到函数外部变量b,所以f2函数不是闭包

(3) 实现一个简单的闭包

function f1() {
	function f2() {
	}
}

上述代码 f2就是闭包,所以也验证了闭包让你可以在一个内层函数中访问到其外层函数的作用域这个概念

二. 为什么要用闭包?

闭包的作用主要有两点:
(1) 高继承和封装性;
(2) 避免全局变量污染。

示例代码如下

function computer() {
    var baseNum = 10;
    return {
        plus: function(a,b) {
            return a + b + baseNum
        },
        div: function(a,b) {
            return a/b/baseNum
        }
    }
}

let res = computer();
res.plus(10,20)

高集成和封装性是因为可以将多个功能模块封装在一个函数里面,这样便于管理和维护

避免全局污染是因为假如函数内部改变了外部变量的值,而函数外部之后又用到了那个变量,这样在函数外部的使用可能不符合预期,所以闭包就是把该变量包裹在了一个局部的作用域里面,从而达到全局变量污染的目的

三. 闭包是怎么工作的?

上述的res变量为什么可以一直访问并改变computer函数里面的值?

(1)普通函数调用

function f1() {
    var baseNum = 10;
    function f2() {
        baseNum++
        console.log(baseNum)
    }
    f2()
}

f1(); //11
f1(); // 11

根据js垃圾回收机制,f1每执行一次,里面的变量就会释放了,即f1函数里面的作用域链AO部分就断了

(2)闭包函数为啥可以保留之前的调用值

function f1() {
   var baseNum = 10;
   return function f2() {
       baseNum++
       console.log(baseNum)
   }
}

var res = f1(); 
res(); // 11
res()  // 12

原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这个全局变量始终在内存中,这导致f2始终在内存中,而f2的存在依赖于f1,f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

四. 使用闭包的注意点

(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

手把手教你学会闭包 的相关文章

  • Makefile 编写教程(由简至难)

    目录 一 测试代码二 c 文件与Makefile同级三 c文件与Makefile不同级四 链接静态库 一 测试代码 本文以将main c add c common h三个文件编译成一个可执行文件为例 xff0c 来讲解Makefile的编写
  • Ubuntu解决 The following signatures couldn‘t be verified because the public key is not available:

    Ubuntu在source list中添加源后 xff0c 提示 The following signatures couldn t be verified because the public key is not available N
  • Ubuntu搭建gitlab-Ci教程

    本文参考gitlab官方教程搭建CI GitLab Runner是一款开源工具 xff0c 用于在GitLab上运行CI CD xff08 持续集成 持续交付 xff09 作业 它可以在多个操作系统上安装和使用 xff0c 并且可以在容器中
  • 常用命令汇总

    tar gz 压缩包 解压 xff1a tar zxvf FileName tar gz 压缩 xff1a tar zcvf FileName tar gz DirName 删除远程分支 span class token function
  • 问题解决:import serial提示 ImportError: No module named serial

    问题 xff1a 在Ubuntu系统中运行python脚本 xff0c 出现如下提示说明pythoh的serial模块没有安装 ImportError No module named serial 解决 网上大部分的解决方法都是安装pyse
  • An Introduction to Deep Learning for the PhysicalLayer

    An Introduction to Deep Learning for the PhysicalLayer I INTRODUCTION 这段主要讲了文章的主要工作 将发射机 通道和接收器作为一个自动编码器 xff0c 对于给定的损失函数
  • 机器学习调制解调器:ML将如何改变我们设计下一代通信系统的方式

    所以 xff0c 我听到你们都在问 xff0c 我们都失业了吗 通信工程师是机器崛起的又一个受害者吗 幸运的是 xff0c 本文中的答案是否定的 但是Nathan Ben和Tim指出了一种新的方式来指定和设计通信系统 xff0c 这可能会永
  • git clone指定分支

    技术背景 Git是代码版本最常用的管理工具 xff0c 此前也写过一篇介绍Git的基本使用的博客 xff0c 而本文介绍一个可能在特定场景下能够用到的功能 直接拉取指定分支的内容 Git Clone 首先看一下如果我们按照常规的操作去拉取一
  • PX4最新版ubuntu编译环境搭建

    PX4最新版ubuntu编译环境搭建 本博客的撰写主要也是博主的自己血泪之路 xff0c 参考了各种博客 xff0c 然而对于我并没有什么卵用 xff0c 简直是成功的都一样 xff0c 不成功的各有各的不同 xff0c 最后在快要放弃而转
  • RTOS滴答Tick设置多少才合适

    本文转载 xff0c 留作笔记 xff0c 如有侵权 xff0c 请联系删除 xff0c 原文链接地址 xff1a 嵌入式开发 RTOS滴答Tick设置多少才合适 xff1f qq com https mp weixin qq com s
  • Darknet-Deep_sort_pytorch 无人机跟踪识别记录

    创建数据集 使用labelme 构造voc数据集格式 转换txt为xml 开始训练 span class token function sudo span span class token function nohup span darkn
  • Docker安装Ubuntu

    local footstep 64 ubuntu ifconfig docker0 flags 61 4163 lt UP BROADCAST RUNNING MULTICAST gt mtu 1500 inet 172 17 0 1 ne
  • MSCKF学习记录

    MSCKF相关资料 1 github参考实现 xff1a daniilidis group msckf mono https github com daniilidis group msckf mono 2 CSND参考博客 xff1a m
  • ARM linux 串口接收

    C语言read函数的使用以及串口初始化的调用 废话不多说 xff0c 直接上代码 xff0c 有疑问可以看我之前的文章 https blog csdn net m0 38053897 article details 108816643 ht
  • 设计模式--状态模式(C语言实现)

    原创 亚索老哥 embed linux share 模式动机 状态模式 状态机 是嵌入式开发中最重要 最核心的设计模式之一 xff0c 毫不夸张的说 xff0c 是否熟练掌握状态模式 xff0c 很大程度上直接决定了嵌入式工程师的代码掌控能
  • 张正友相机标定 及 一文讲透鱼眼相机畸变矫正,及目标检测项目应用

    参考链接 xff1a 相机标定 张正友标定法 一文讲透鱼眼相机畸变矫正 xff0c 及目标检测项目应用
  • select在ios中选项空白

    出现这个问题是因为粗心吧 解决了好久 最后发现是个笑话 lt select name 61 span class hljs string 34 34 span id 61 span class hljs string 34 34 span
  • RTOS中消息、信号量、互斥量、事件使用区别(类比理解)

    RTOS中消息 信号量 互斥量 事件使用区别 xff08 类比理解 xff09 注 xff1a 本文仅代表本人学习中的理解 xff0c 未必正确 xff0c 欢迎指正 xff01 1 消息 1 1 对FreeRTOS 就像往火车上装货卸货
  • PuTTY/Xshell连接远程服务器提示connection time out的解决方案

    刚注册一台云服务器时 xff0c 想使用PuTTY Xshell来在本地远程连接服务器 xff0c 发现会出现以下错误提示 xff1a Network error Connection time out 对于新注册的云服务器 xff0c 什

随机推荐

  • Ubuntu编译环境配置

    1 升级gcc sudo apt get update sudo apt get install software properties common sudo apt get install gcc 5 g 43 5 sudo apt g
  • 多传感器融合的四种经典结构

    人一生的成长过程中 xff0c 也不总是只有一种必然性 xff0c 很多时候 xff0c 人生需要选择 请选择有尊严的活着 xff0c 告别卑微 xff01 转一篇信息融合的结构概述 xff1a 多传感器信息融合的结构模型一般有四种基本形式
  • 认识Make、Makefile、CMake和CMakeLists

    一 Make 在 认识编译器和C C 43 43 编译 一文中介绍过 xff0c 一个 c cpp 文件从源文件到目标文件的过程叫做编译 xff0c 但是一个项目中不可能只存在一个文件 xff0c 这就涉及到多个文件的编译问题 xff0c
  • 卡尔曼滤波基础---MATLAB

    Karl Gauss xff08 1795年 xff09 行星轨道测量 最小二乘估计法 Norbert Wiener xff08 1942年 xff09 火力控制系统精确跟踪 Wiener Kolmogorov滤波 Rudolf Kalma
  • 位姿估计 -- PPF算法的OpenCV实现

    给出cpp代码 xff0c 复制粘贴改一下文件路径记得 1 pose cpp span class token comment span span class token comment Created by yaohua on 2020
  • 针对ROS配置VScode开发环境(catkin_make 或 catkin build)

    针对ROS配置VScode开发环境 xff08 catkin make 或 catkin build xff09 使用catkin make ubuntu 18的vscode配置ros开发环境 xff1a catkin make span
  • 电脑双系统即在windows系统与Linux系统中如何设置默认启动系统

    来源 xff08 https www bilibili com read cv5277001 xff09
  • Ubuntu添加/删除PPA源

    一 PPA介绍 PPA xff08 Personal Package Archives xff0c 个人软件包文档 xff09 xff0c 是Ubuntu Launchpad网站提供的一项源服务 xff0c 允许个人用户上传软件源代码 xf
  • 操作系统之进程概念及其组成

    一 进程 在多道程序环境下 xff0c 允许多个程序并发执行 xff0c 此时它们将失去封闭性 xff0c 并具有间断性及不可 再现性的特征 为此引入了进程 Prnccss 的概念 xff0c 以便更好地描述和控制程序的并发执行 xff0c
  • GTSAM中imu预积分及其因子图优化过程

    前言 使用IMU和llidar或者相机进行多传感器融合的slam方案中 xff0c 主要分为紧耦合和松耦合方案 目前 xff0c 主流的方案都是紧耦合的 而紧耦合方案中主要分为基于滤波 xff08 比如 xff0c ESKF xff09 和
  • Python 学习笔记 模块 & 目录遍历 & 包

    一 模块 xff1a 1 概述 xff1a 为了解决维护问题 xff0c 一般情况下 xff0c 在一个完整的项目中 xff0c 会将特定的功能分组 xff0c 分别放到不同的文件中 xff0c 在使用的过程中 xff0c 可以单独维护 x
  • realsense-ros环境配置

    项目场景 xff1a 相机型号RealsenseD435i 环境 xff1a ubuntu1604 xff0c 内核4 15 0 126 generic uname r可查看内核 参考链接 xff1a https github com In
  • realsense相机SDK——librealsense使用方法及bug解决(ubuntu)

    realsense环境配置参考https blog csdn net m0 43436602 article details 110930512 一 librealsense在哪里 xff1f 安装完环境之后 xff0c 可以去根目录下搜一
  • uCOS消息队列相关函数的理解

    OSQCreate xff1a 创建消息队列函数 有四个入口参数 xff1a 消息队列指针 xff1b 消息队列名称 xff1b 消息队列大小 xff08 不能为0 xff09 xff1b 返回错误类型 函数过程 xff1a 首先进行安全检
  • uCOS任务信号量相关函数代码理解

    强调任务信号量思想 xff1a 任务信号量只是一个标志 xff0c 获取成功就是指把信号量计数值减1 xff1b 释放就是指把信号量计数值加1 xff08 溢出则计数值不变 xff09 获取信号量需要判断信号量是否可用 xff08 大于0
  • (二)灰度图像二值化

    灰度图像二值化 一 知识简介 图像二值化 xff08 Image Binarization xff09 就是将图像上的像素点的灰度值设置为0或255 xff0c 也就是将整个图像呈现出明显的黑白效果的过程 在数字图像处理中 xff0c 二值
  • Modbus RS485 设备的串口调试

    Modbus RS485 设备的串口调试 准备Modbus功能码二 使用步骤1 接线2 串口调试 温湿度的计算 准备 硬件设备 xff1a 电脑 RS485 温湿度传感器 RS485 土壤温湿度传感器 RS485 继电器控制模块 TTL转R
  • Linux为什么区分内核空间和用户空间

    程序如果要被CPU执行 xff0c 就得编译成CPU可以执行的指令 xff0c 一大堆的程序就变成了一堆的指令 一个操作系统它也是一堆程序组成的 xff0c 可以想象CPU的指令是很多的 xff0c 但是这么多的指令中 xff0c 有些指令
  • 【Docker】镜像的保存(save)到文件 与 加载(load)到宿主机

    背景 xff1a 我们制作好的镜像会存储在宿主机上 xff0c 那么在迁移的过程中 xff0c 我们应该如何 保存自定义的镜像到宿文件 或 加载自定义的镜像到宿主机呢 xff1f 制作镜像 xff1a docker build t 镜像名
  • 手把手教你学会闭包

    前言 MDN对闭包的解释是这样的 xff1a 一个函数和对其周围状态 xff08 lexical environment xff0c 词法环境 xff09 的引用捆绑在一起 xff08 或者说函数被引用包围 xff09 xff0c 这样的组