【JS】理解闭包及其应用

历史小剧场

明朝灭亡,并非是简单的政治问题,事实上,这是世界经济史上的一个重要案例。
所谓没钱,就是没有白银。----《明朝那些事儿》

什么是闭包?

闭包就是指有权访问另一个函数作用域中变量的函数

闭包变量存储位置?

  • 堆内存

假如闭包中的变量存储在栈内存中,那么栈的回收,会把处于栈顶的变量自动回收。所以闭包中的变量如果处于栈中那么变量被销毁后,闭包中的变量就没有了。所以闭包中的变量是处于堆内存中的。

闭包的作用?

  • 创造私有变量,且延长私有变量的生命周期

应用

  1. 延伸函数生命周期
function hd() {let n = 1;return function sum() {console.log(++n)}sum()
}
let a = hd();
a(); // 2
a(); // 3
a(); // 4
a(); // 5
a(); // 6
let b = hd()
b() // 2
b() //3
let c = hd()
c() // 2console.log("---------- 用完就删 --------")
function hd2() {let n = 1;function sum() {console.log(++n)}sum()
}
hd2()   // 2
hd2()   // 2
hd2()   // 2console.log("-------------------------------")
const hd3 = () => {let n = 1;return () => {const m = () => console.log(++n)m()}
}
hd3()() // 2
hd3()() // 2console.log("-------------------------------")
const hd4 = () => {let n = 1;return () => {return () => console.log(++n)}
}
const h4 = hd4()()
h4();   // 2
h4();   // 3
h4();   // 4
  1. var/let 在for循环中的执行原理
for (var i = 1; i <= 3; i++) {console.log(`for里面:${i}`)
}
console.log(`for外面:${i}`) // 4for (let j = 1; j <= 3; j++) {console.log(`for里面: ${j}`)
}
// console.log(`for外面: ${j}`) // ReferenceError: j is not definedconsole.log("------------------------------")
for (var k = 1; k <= 3; k++) {setTimeout(() => {console.log(`var timeout for里面: ${k}`)    // 4 4 4}, 1000)
}console.log("-------------------------------")
for (let l = 1; l <= 3; l++) {setTimeout(() => {console.log(`let timeout for里面: ${l}`)    // 1 2 3}, 1000)
}
  1. 多层作用域嵌套
let arr1 = [];
for (let i = 1; i <= 3; i++) {arr1.push(() => i)
}
console.log(arr1[0]()); // 1
console.log(arr1[1]()); // 2
console.log(arr1[2]()); // 3console.log("----------------------")
let arr2 = [];
for (var i = 1; i <= 3; i++) {arr2.push(() => i)
}
console.log(arr2[0]()) // 4
console.log(arr2[1]()) // 4
console.log(arr2[2]()) // 4console.log("------------------")
let arr3 = [];
for (var i = 1; i <= 3; i++) {((i) => arr3.push(() => i))(i)
}
console.log(arr3[0]()) // 1
console.log(arr3[1]()) // 2
console.log(arr3[2]()) // 3
  1. 获取商品区间以及商品排序

商品区间

const goods = [{title: "A",price: 30,},{title: "B",price: 10,},{title: "C",price: 50,},{title: "D",price: 20,},{title: "E",price: 40,},{title: "F",price: 60,},{title: "G",price: 300,},{title: "H",price: 80,},{title: "I",price: 20,},{title: "J",price: 200}
]
console.log("---------------- 商品区间 -----------------")
const getPriceRange = (begin, end) => (val) => val.price >= begin && val.price <= end;
console.table(goods.filter(getPriceRange(20, 50))); // [ { title: 'B', price: 10 }, { title: 'D', price: 20 }, { title: 'E', price: 40 }, { title: 'F', price: 60 }, { title: 'I', price: 20 } ]
console.table(goods.filter(getPriceRange(40, 200))); 

运行结果:
在这里插入图片描述

商品排序

const sortGoods = (key, order = "asc") => (a, b) => order === "asc"? a[key] - b[key] : b[key] - a[key];
console.table(goods.sort(sortGoods("price"))); // [ { title: 'B', price: 10 }, { title: 'D', price: 20 }, { title: 'E', price: 40 }, { title: 'F', price: 60 }, { title: 'I', price: 20 }, { title: 'A', price: 30 }, { title: 'C', price: 50 }, { title: 'H', price: 80 }, { title: 'J', price: 200 }, { title: 'G', price: 300 } ]
console.table(goods.sort(sortGoods("price", "desc"))); 

运行结果:
在这里插入图片描述
5. 移动动画的闭包使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>body {position: relative;}button {position: absolute;}</style>
</head>
<body><!-- <button>你好</button> --><button>真好</button><script>const btns = document.querySelectorAll('button');// btns.forEach((btn) => {//     // parent//     let left = 1;//     btn.addEventListener('click', () => {//         setInterval(() => {//             console.log(left)//             btn.style.left = `${left++}px`;//         }, 100) // 会抖动//     })// })btns.forEach(btn => {let bind = false;btn.addEventListener('click', () => {if (!bind) {let left = 1;bind = setInterval(() => {console.log(left)btn.style.left = `${left++}px`;}, 100)  // 不会抖动}})})</script>
</body>
</html>
  1. 实现缓存模拟localStorage
  • 可以通过set方法存值,get方法取值
const myStorage = (function () {const cache = {}return {set: (key, val) => {cache[key] = val},get: (key) => {if (Object.prototype.hasOwnProperty.call(cache, key)) {return cache[key]}}}
})()myStorage.set('name', 'Tom')
myStorage.set('age', 20)
console.log(myStorage.get('name')) //   Tom
console.log(myStorage.get('age')) //   20

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

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

相关文章

Lidar3607.2 雷达点云数据处理软件新增功能介绍

新特性:预处理航带平差新增livox激光器镜面误差改正,新增多源航带平差&#xff0c;提升点云和影像匹配精度优化配准功能流程&#xff0c;ICP功能支持点云与模型配准安置检校新增轨迹自动裁剪轨迹解算时投影坐标增加Z值记录数据管理新增点云色彩亮度和对比度调节新增多段线平滑工…

Python中报错提示:TypeError: Student() takes no arguments

Python中报错提示&#xff1a;TypeError: Student() takes no arguments 在Python编程中&#xff0c;类是创建对象的蓝图。每个类都可能包含一个特殊的方法__init__&#xff0c;我们称之为构造函数&#xff0c;它在创建新实例时被调用。如果你在尝试创建一个类的实例时遇到了Ty…

端午节赛龙舟,我们的新队员---AI大模型

赛龙舟的比赛通常在一个湖泊或河流上进行&#xff0c;参赛队伍会驾驭着长形的龙舟&#xff0c;每艘船上有一名鼓手和多名桨手。比赛开始时&#xff0c;鼓手会击鼓来指挥桨手的划桨节奏&#xff0c;而桨手们则要协同合作&#xff0c;以最快的速度将龙舟划向终点。 赛龙舟不仅仅是…

【SpringCloud学习笔记】Docker(中篇)

Docker 1. 自定义镜像 前面我们都是使用docker pull拉取仓库中现成的镜像&#xff0c;但是如果我们想要将一个Java应用程序构建成镜像然后部署应该怎么做呢&#xff1f;这个时候我们就需要自定义镜像了 **镜像&#xff1a;**本质上就是一堆文件的集合&#xff0c;包含了应用程…

【清华大学】《自然语言处理》(刘知远)课程笔记 ——NLP Basics

自然语言处理基础&#xff08;Natural Language Processing Basics, NLP Basics&#xff09; 自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言…

临床应用的深度学习在视网膜疾病的诊断和转诊中的应用| 文献速递-视觉通用模型与疾病诊断

Title 题目 Clinically applicable deep learning for diagnosis and referral in retinal disease 临床应用的深度学习在视网膜疾病的诊断和转诊中的应用 01 文献速递介绍 诊断成像的数量和复杂性正在以比人类专家可用性更快的速度增加。人工智能在分类一些常见疾病的二…

归并排序-成绩输出-c++

注&#xff1a;摘自hetaobc-L13-4 【任务目标】 按学号从小到大依次输入n个人的成绩&#xff0c;按成绩从大到小输出每个人的学号&#xff0c;成绩相同时学号小的优先输出。 【输入】 输入第一行为一个整数&#xff0c;n&#xff0c;表示人数。&#xff08;1 ≤ n ≤ 100000…

【Node.js快速部署opencv项目】图像分类与目标检测

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

高考之后第一张大流量卡应该怎么选?

高考之后第一张大流量卡应该怎么选&#xff1f; 高考结束后&#xff0c;选择一张合适的大流量卡对于准大学生来说非常重要&#xff0c;因为假期期间流量的使用可能会暴增。需要综合考虑多个因素&#xff0c;以确保选到最适合自己需求、性价比较高且稳定的套餐。以下是一些建议…

BM算法举例

BM算法概述 Boyer-Moore算法(BM算法)是一种高效的字符串匹配算法。它通过在匹配过程中尽可能多地跳过不必要的字符比较来加速搜索过程。BM算法主要利用两个启发规则:坏字符规则(Bad Character Rule)和好后缀规则(Good Suffix Rule)。 以下是Boyer-Moore算法的Python实现…

【Python机器学习】非负矩阵分解(NMF)

非负矩阵分解&#xff08;NMF&#xff09;也是一种无监督算法&#xff0c;其目的在于提取有用的特征。它的工作原理类似于PCA&#xff0c;也可以用于降维。与PCA相同&#xff0c;我们试图将每个数据点写成一些分量的加权求和。但在PCA中&#xff0c;我们想要的是正交分量&#…

Linux——PXE整体流程

1.自己安装一个CentOS 8的服务器 1&#xff09;手动安装 虚拟硬件配置&#xff1a;2核CPU&#xff0c;4G内存&#xff0c;100G硬盘 2个网卡&#xff08;一个通外网&#xff0c;一个内部使用&#xff09; 软件安装&#xff1a;Server GUI 磁盘分区&#xff1a;使用逻辑卷&#…

小黑狗AI:新媒体AI创作的得力助手

在当前内容创作爆炸的时代,如何高效、优质地输出内容备受重视。小黑狗AI凭借强大的AI技术,专注于为新媒体内容创作者提供智能化的辅助工具,旨在成为创作者们最听话、最贴心的AI助手。 专注新媒体AI创作&#xff0c;争做最听话的AI工具&#xff1a;小黑狗AI 功能一览 小黑狗A…

Django API开发实战:前后端分离、Restful风格与DRF序列化器详解

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…

中心极限定理的MATLAB例

独立同分布的中心极限定理&#xff1a; 设 X 1 , X 2 , … , X n X_1, X_2, \ldots, X_n X1​,X2​,…,Xn​ 是独立同分布的随机变量序列&#xff0c;且 E ( X i ) μ E(X_i) \mu E(Xi​)μ&#xff0c; D ( X i ) σ 2 > 0 D(X_i) \sigma^2 > 0 D(Xi​)σ2>0&a…

《C++ Primer Plus》第十三章复习题和编程练习

目录 一、复习题**二、编程练习 一、复习题** 1. 派生类从基类那里继承了什么&#xff1f; 答&#xff1a;在类的继承和派生中&#xff0c;C中的派生类能够继承基类的所有数据成员和大部分成员函数。但是基类中不同访问控制权限的成员在派生中的访问权限也不相同。公有成员直…

【GIT】git submodule add 命令的使用技巧,亲测可行

在Git中&#xff0c;git submodule add 命令用于将一个外部的Git仓库作为子模块添加到当前的Git仓库中。子模块允许你将一个Git仓库作为另一个Git仓库的子目录。这在你需要将一个项目的一部分作为另一个项目的依赖时非常有用。 使用 git submodule add 命令的基本语法如下&…

快速将字符串转换为python数据类型

可以使用 python 中的 eval() 函数&#xff0c;举例如下&#xff0c;我需要将大模型输出字符串转换为 numpy 数据类型 import numpy as np import ast# 原始字符串 s "[(-0.014,0.009),(0.005,-0.027),(-0.008,0.006),(-0.014,0.014)]"# 安全地解析字符串中的表达式…

陆面生态水文模拟与多源遥感数据同化技术

原文链接&#xff1a;陆面生态水文模拟与多源遥感数据同化技术 了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用;熟悉模 型的发展历程&#xff0c;常见模型及各自特点;理解Noah-MP模型的原理&#xff0c;掌握Noah-MP 模型在单 站和区域的模拟、模拟结果的…

如何将AndroidStudio和IDEA的包名改为分层级目录

新版UIAndroidStudio 1、点击项目目录右上角如图所示的三个点点。 2、然后依次取消Hide empty middle package &#xff0c;Flatten package的勾选 3、注意&#xff1a;一定要先取消hide的勾选&#xff0c;不然目录不会完全分级&#xff08;做错了可以反过来重新设置&#x…