javascript基础六:说说你对闭包的理解?闭包使用场景?

在这里插入图片描述
一、是什么
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)
也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域

在 JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁

举个粟子

function init() {
    var name = "小爱同学"; // name 是一个被 init 创建的局部变量
    function displayName() { // displayName() 是内部函数,一个闭包
        alert(name); // 使用了父函数中声明的变量
    }
    displayName();
}
init();

displayName() 没有自己的局部变量。然而,由于闭包的特性,它可以访问到外部函数的变量

二、使用场景

任何闭包的使用场景都离不开这两点:

  • 创建私有变量
  • 延长变量的生命周期

一般函数的词法环境在函数返回后就被销毁,但是闭包会保存对创建时所在词法环境的引用,即便创建时所在的执行上下文被销毁,但创建时所在词法环境依然存在,以达到延长变量的生命周期的目的

下面举个粟子
在页面上添加一些可以调整字号的按钮


function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

柯里化函数
柯里化的目的在于避免频繁调用具有相同参数函数的同时,又能够轻松的重用


// 假设我们有一个求长方形面积的函数
function getArea(width, height) {
    return width * height
}
// 如果我们碰到的长方形的宽老是10
const area1 = getArea(10, 20)
const area2 = getArea(10, 30)
const area3 = getArea(10, 40)

// 我们可以使用闭包柯里化这个计算面积的函数
function getArea(width) {
    return height => {
        return width * height
    }
}

const getTenWidthArea = getArea(10)
// 之后碰到宽度为10的长方形就可以这样计算面积
const area1 = getTenWidthArea(20)

// 而且如果遇到宽度偶尔变化也可以轻松复用
const getTwentyWidthArea = getArea(20)

使用闭包模拟私有方法
在JavaScript中,没有支持声明私有变量,但我们可以使用闭包来模拟私有方法
下面举个例子:

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }
})();

var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */

上述通过使用闭包来定义公共函数,并令其可以访问私有函数和变量,这种方式也叫模块方式

两个计数器 Counter1 和 Counter2 是维护它们各自的独立性的,每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境,不会影响另一个闭包中的变量

其他
例如计数器、延迟调用、回调等闭包的应用,其核心思想还是创建私有变量和延长变量的生命周期

三、注意事项
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响
例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。

原因在于每个对象的创建,方法都会被重新赋值


function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

上面的代码中,我们并没有利用到闭包的好处,因此可以避免使用闭包。修改成如下:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CDN加速在网站建设中的应用

近年来,随着互联网技术的不断发展,互联网行业迎来了井喷式发展,各类网站如雨后春笋般不断涌现,网站数量迅速增长,但与此同时也导致网站响应速度慢、访问不流畅等问题。因此,如何优化网站的性能、提高网站的…

【算法】简单讲解如何使用两个栈实现一个队列

文章目录 什么是栈和队列?设计思路代码实现 什么是栈和队列? 栈和队列其实大家基本都知道是什么,或者说,最基本的,他们的特性我们是知道的。 栈是一种FILO先进后出的数据结构,队列是一种FIFO先进先出的数据…

IP-Guard客户端上插入加密盘时提示格式化,能否禁止该弹窗?

客户端上插入加密盘时提示格式化,能否禁止该弹窗? 1、当Shell Hardware Detection服务启动时,操作系统检测硬件的速度要快于客户端,而此时操作系统是不能识别加密后的移动盘的,因此认为加密盘异常,提示需要格式化,策略-客户端配置,选择禁止windows7播放功能。配置后不…

华为OD机试题【字符统计】【2023 B卷 100分】

文章目录 🎯 前言🎯 题目描述🎯 解题思路📙 Python代码实现📗 Java代码实现📘 C语言代码实现 🎯 前言 🏆 《华为机试真题》专栏含2023年牛客网面经、华为面经试题、华为OD机试真题最…

【快应用】多语言适配案例

【关键词】 多语言,$t 【问题背景】 快应用平台的能力会覆盖多个国家地区,平台支持多语言的能力后,可以让一个快应同时支持多个语言版本的切换,开发者无需开发多个不同语言的源码项目,避免给项目维护带来困难。使用系…

《Datawhale南瓜书》出第二版啦!

Datawhale干货 作者:Datawhale开源项目团队 作为机器学习的入门经典教材,周志华老师的《机器学习》,自2016年1月底出版以来,首印5000册一周售罄,并在8个月内重印9次。先后登上了亚马逊,京东,当…

[数据集][目标检测]目标检测数据集绝缘子缺陷防震锤1688张5类别VOC格式

数据集格式:Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):1688 标注数量(xml文件个数):1688 标注类别数:5 标注类别名称:["flashover",&…

00): Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)

好久没有使用数据库, 连接数据库报上面的错误,尝试了网上的方法还是没有成功,思索之后想起之前手动关闭了mysql的服务,Windows启动时mysql服务不会自动启动,成功启动mysql服务后再次连接数据库,正常连接。 …

PGXC GaussDB

PGXCA PGXC(PostgreSQL eXtended Coordinator)是一个基于 PostgreSQL 架构的分布式数据库解决方案。它扩展了 PostgreSQL,为用户提供了在多个节点上分布式存储和处理数据的能力。 PGXC 的设计目标是将 PostgreSQL 扩展为能够处理大规模数据…

Java课程设计之购物车管理系统

一、项目准备 1、开发工具:JDK、Eclipse 2、需求分析: 包括商品管理和购物车管理。 1)商品管理主要功能 商品信息导入 显示所有商品信息 2)购物车主要功能 添加商品到购物车 修改购物车中的商品数量 显示购物车中的所有商…

MockServer 服务框架设计

【摘要】 大部分现有的 mock 工具只能满足 HTTP 协议下简单业务场景的使用。但是面对一些复杂的业务场景就显得捉襟见肘,比如对 socket 协议的应用进行 mock,或者对于支付接口的失败重试的定制化 mock 场景。为解决上述问题,霍格沃兹测试学院…

pdf怎么合并成一个文件?高效工具分享

PDF是一种非常常用的文档格式,许多人经常需要合并多个PDF文件为一个文件。这是因为有时候我们需要将多个PDF文件打包成一个文件,以便于共享或归档。在本文中,我们将介绍如何使用电脑或手机合并PDF文件。 以下是常见的合并PDF的软件&#xff1…

Java中的this、package、import

this 在Java中,this的作用和其词义很接近。 它在方法内部使用,即这个方法所属对象的引用; 它在构造器内部使用,表示该构造器正在初始化的对象。 this 可以调用类的属性、方法和构造器 什么时候使用this关键字呢&#xff…

Socket(七)

文章目录 1. 单文件服务器2. 重定向器Redirector3. 功能完备的HTTP服务器 1. 单文件服务器 要研究HTTP服务器,先从一个简单的服务器开始,无论接受什么请求,这个服务器都始终发送同一个文件。这个单文件服务器名为SingleFileHTTPServer&#…

车辆CAN信号,依据DBC文件解析流程

CAN信号解析流程 1.车辆CAN对应dbc文件 DBC文件是一种用于描述CAN(Controller Area Network)数据通信协议的文件格式,DBC文件中包含了CAN数据的信号定义、编码方式、单位、范围等信息,可以用于解析和生成CAN数据帧。 一个DBC文件…

ChatGPT的4个不为人知却非常实用的小功能

重点介绍四个ChatGPT很实用的小功能。 一、停止生成 如果在ChatGPT输出内容的过程中,我们发现结果不是自己想要的,可以直接点击“Stop generating”按钮,这样它就会立即停止输出。 二、复制功能 在ChatGPT返回对话的右侧,有三个图…

MySQL主存复制

介绍 配置-主库master 第一步:修改MySQL数据库的配置文件/etc/my.cnf [mysqld] log-binmysql-bin #[必须]启用二进制日志 server-id100 #[必须]服务器唯一id第二部:重启MySQL服务 systemctl restart mysqld第三步:登录MySQL操作&#x…

Linux:软件管理器yum编辑器vim

软件管理器yum&&编辑器vim 🔆软件管理器yum软件包是什么rzsz网络通畅性验证查看软件包怎么安装软件安装yum扩展源怎么卸载软件 🔆编辑器vim基本概念基本操作正常模式指令集末行模式指令集简单配置vim配置文件的位置常用配置选项使用插件参考资料…

DVWA——Brute Force

文章目录 Brute Force(暴力(破解))(1)Low等级(2)Medium等级(3)High等级(4)Impossible Brute Force(暴力(破解&…

chatgpt赋能python:Python如何快速复制上一行?

Python 如何快速复制上一行? 在编写Python代码时,经常需要快速复制上一行代码进行修改。如果只是简单的手动复制粘贴,会造成不必要的时间浪费并且容易出错。本文将介绍三种快速复制上一行代码的方法。 方法一:使用快捷键 在Pyt…