【JS】理解闭包及其应用

news2024/11/25 23:49:32

历史小剧场

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

什么是闭包?

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

闭包变量存储位置?

  • 堆内存

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

闭包的作用?

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

应用

  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() // 2

console.log("---------- 用完就删 --------")
function hd2() {
    let n = 1;
    function sum() {
       console.log(++n)
    }
    sum()
}
hd2()   // 2
hd2()   // 2
hd2()   // 2


console.log("-------------------------------")
const hd3 = () => {
    let n = 1;
    return () => {
        const m = () => console.log(++n)
        m()
    }
}
hd3()() // 2
hd3()() // 2


console.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}`) // 4


for (let j = 1; j <= 3; j++) {
    console.log(`for里面: ${j}`)
}
// console.log(`for外面: ${j}`) // ReferenceError: j is not defined


console.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]()); // 3


console.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]()) // 4

console.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.coloradmin.cn/o/1805824.html

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

相关文章

数据结构【堆排序】

前言 在上一篇文章主要讲解了二叉树的基本概念和堆的概念以及接口的实现&#xff08;点此处跳转&#xff09; 我们简回顾下堆的基本概念&#xff1a; 1.堆分为大堆和小堆 大堆&#xff1a;父亲结点比左右孩子都大&#xff0c;根结点是最大的小堆&#xff1a;父亲结点比左右孩…

关于CodeCombat(沙漠)布朗噪声的攻略

关于CodeCombat(沙漠)//布朗噪声的攻略 总的来说怎么猥琐怎么来 1.走到墙角骷髅看不到的位置&#xff0c;让宠物制造噪音&#xff0c;然后英雄走过去&#xff0c;就是这样没错&#xff08;坐标之类能明白) 最后看看运行结果吧 Rec 0002 希望天天开心

CAN协议简介

协议简介 can协议是一种用于控制网络的通信协议。它是一种基于广播的多主机总线网络协议&#xff0c;常用于工业自动化和控制领域。can协议具有高可靠性、实时性强和抗干扰能力强的特点&#xff0c;被广泛应用于汽车、机械、航空等领域。 can协议采用了先进的冲突检测和错误检测…

C++系统编程篇——linux软件包管理器yum

Linux 软件包管理器yum (1)linux系统&#xff08;centos生态&#xff09; 安装方式有三种&#xff1a;源代码安装、rpm安装、yum安装&#xff08;最简单&#xff09; ls /etc/yum.repos.d/ 查看该路径下的文件 包含了用于配置 YUM 软件包管理器的仓库配置文件。这些配置文件…

QT-轻量级的笔记软件MyNote

MyNote v2.0 一个轻量级的笔记软件&#x1f4d4; Github项目地址: https://github.com/chandlerye/MyNote/tree/main 应用简介 MyNote v2.0 是一款个人笔记管理软件&#xff0c;没有复杂的功能&#xff0c;旨在提供便捷的笔记记录、管理以及云同步功能。基于Qt 6.6.3 个人开…

ASUS华硕ROG幻14Air笔记本GA403UI(UI UV UU UJ)工厂模式原厂Windows11系统安装包,带MyASUS in WinRE重置还原

适用型号&#xff1a;GA403UI、GA403UV、GA403UU、GA403UJ 链接&#xff1a;https://pan.baidu.com/s/1tz8PZbYKakfvUoXafQPLIg?pwd1mtc 提取码&#xff1a;1mtc 华硕原装WIN11系统工厂包带有ASUS RECOVERY恢复功能、自带面部识别,声卡,显卡,网卡,蓝牙等所有驱动、出厂主题…

大模型的演进之路:从萌芽到ChatGPT的辉煌

文章目录 ChatGPT&#xff1a;大模型进化史与未来展望引言&#xff1a;大模型的黎明统计模型的奠基深度学习的破晓 GPT系列&#xff1a;预训练革命GPT的诞生&#xff1a;预训练微调的范式转换GPT-2&#xff1a;规模与能力的双重飞跃GPT-3&#xff1a;千亿美元参数的奇迹 ChatGP…

(三)React事件

1. React基础事件绑定 语法&#xff1a; on 事件名称 { 事件处理程序 }&#xff0c;整体上遵循驼峰命名法 App.js //项目根组件 //App -> index.js -> public/index.html(root)function App() {const handleClick () > {console.log(button被点击了)}return (<…

Data Mining2 复习笔记6 - Optimization Hyperparameter Tuning

6. Optimization & Hyperparameter Tuning Why Hyperparameter Tuning? Many learning algorithms for classification, regression, … Many of those have hyperparameters: k and distance function for k nearest neighbors, splitting and pruning options in decis…

【JS】立即执行函数IIFE 和闭包到底是什么关系?

历史小剧场 ”我希望认您作父亲&#xff0c;但又怕您觉得我年纪大&#xff0c;不愿意&#xff0c;索性让我的儿子给您作孙子吧&#xff01;“ ----《明朝那些事儿》 什么是立即执行函数&#xff1f; 特点&#xff1a; 声明一个匿名函数马上调用这个匿名函数销毁这个匿名函数 …

湖南(品牌控价)源点调研 手机价格管理对品牌的影响分析

前言&#xff1a;手机自发明以来&#xff0c;过去一直是国际品牌占主导地位&#xff0c;从最初的爱立信、摩托罗拉&#xff0c;到后来的诺基亚、三星&#xff0c;苹果在这个手机行业里&#xff0c;竞争激励&#xff0c;没有百年企业&#xff0c;每个品牌的盛衰都有背后的历史背…

transformer中对于QKV的个人理解

目录 1、向量点乘 2、相似度计算举例 3、QKV分析 4、整体流程 (1) 首先从词向量到Q、K、V (2) 计算Q*&#xff08;K的转置&#xff09;&#xff0c;并归一化之后进行softmax (3) 使用刚得到的权重矩阵&#xff0c;与V相乘&#xff0c;计算加权求和。 5、多头注意力 上面…

VMware Fusion 如何增加linux硬盘空间并成功挂载

文章目录 0. 前言1. 增加硬盘空间2. 硬盘分区2.1 查看硬盘2.2 分区2.3 格式化2.4 挂载 3. 参考 0. 前言 如果发现虚拟机分配的硬盘不足&#xff0c;需要增加硬盘空间。本文教给大家如何增加硬盘空间并成功挂载。 查看当前硬盘使用情况&#xff1a; df -h可以看到&#xff0c…

使用 GPT-4 创作高考作文 2024年

使用 GPT-4 创作高考作文 2024年 使用 GPT-4 创作高考作文&#xff1a;技术博客指南 &#x1f914;✨摘要引言正文内容&#xff08;详细介绍&#xff09; &#x1f4da;&#x1f4a1;什么是 GPT-4&#xff1f;高考作文题目分析 ✍️&#x1f9d0;新课标I卷 人类智慧的进步&…

二次规划问题(Quadratic Programming, QP)原理例子

二次规划(Quadratic Programming, QP) 二次规划(Quadratic Programming, QP)是优化问题中的一个重要类别,它涉及目标函数为二次函数并且线性约束条件的优化问题。二次规划在控制系统、金融优化、机器学习等领域有广泛应用。下面详细介绍二次规划问题的原理和求解过程 二…

k8s学习--kubernetes服务自动伸缩之垂直伸缩(资源伸缩)VPA详细解释与安装

文章目录 前言VPA简介简单理解详细解释VPA的优缺点优点1.自动化资源管理2.资源优化3.性能和稳定性提升5.成本节约6.集成性和灵活性 缺点1.Pod 重启影响可用性2.与 HPA 冲突3.资源监控和推荐滞后&#xff1a;4.实现复杂度&#xff1a; 核心概念Resource Requests 和 Limits自动调…

多曝光融合算法(三)cv2.createAlignMTB()多曝光图像融合的像素匹配问题

文章目录 1.cv2.createAlignMTB() 主要是计算2张图像的位移&#xff0c;假设位移移动不大2.多曝光图像的aline算法&#xff1a;median thresold bitmap原理讲解3.图像拼接算法stitch4.多曝光融合工具箱 1.cv2.createAlignMTB() 主要是计算2张图像的位移&#xff0c;假设位移移动…

开发做前端好还是后端好?

目录 一、引言 二、两者的对比分析 技能要求和专业知识&#xff1a; 职责和工作内容&#xff1a; 项目类型和应用领域&#xff1a; 就业前景和市场需求&#xff1a; 三、技能转换和跨领域工作 评估当前技能&#xff1a; 确定目标领域&#xff1a; 掌握相关框架和库&a…

端午节大家都放假了吗

端午节作为中国四大传统节日之一&#xff0c;具有深厚的文化内涵和广泛的群众基础&#xff0c;因此&#xff0c;在这个节日里发布软文&#xff0c;可以围绕其传统习俗、美食文化、家庭团聚等方面展开&#xff0c;以吸引读者的兴趣。 首先&#xff0c;可以从端午节的起源和传统习…

轴承接触角和受力分析

提示&#xff1a;轴承接触角和受力分析 文章目录 1&#xff0c;接触角2&#xff0c;轴承受力分析 1&#xff0c;接触角 所谓公称接触角就是指轴承在正常状态下&#xff0c; 滚动体和内圈及外圈沟道接触点的法线与轴心线的垂直平面之间的夹角。 按滚动轴承工作时所能承受载荷的…