”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解 JavaScript 中的闭包:综合指南

了解 JavaScript 中的闭包:综合指南

发布于2024-07-30
浏览:231

Understanding Closures in JavaScript: A Comprehensive Guide

JavaScript 是一种多功能且强大的语言,其最有趣的功能之一就是闭包的概念。闭包是理解 JavaScript 函数如何工作的基础,尤其是与作用域和变量访问相关的函数。在本教程中,我们将探讨什么是闭包、它们如何工作,并提供实际示例来帮助您掌握这个概念。

什么是闭包?

闭包是一个保留对其词法作用域的访问的函数,即使该函数是在该作用域之外执行的。简单来说,闭包允许函数“记住”它被创建的环境。

为什么闭包很重要?

闭包是必不可少的,原因如下:

  • 数据隐私:闭包使您能够创建无法从函数外部访问的私有变量。

  • 有状态函数:它们允许函数在调用之间维护状态。

  • 函数式编程:闭包是函数式编程中的一个关键概念,它支持高阶函数和柯里化。

闭包如何工作?

为了理解闭包,让我们从一个基本示例开始:

function outerFunction() {
    let outerVariable = 'I am outside!';

    function innerFunction() {
        console.log(outerVariable);
    }

    return innerFunction;
}

const myClosure = outerFunction();
myClosure(); // Output: I am outside!

上例中:

  • outerFunction创建变量outerVariable并定义innerFunction.

  • innerFunction访问位于其词法范围内的outerVariable。

  • outerFunction返回innerFunction,创建一个闭包。

  • 当myClosure被调用时,即使outerFunction已经执行完毕,它仍然可以访问outerVariable。

闭包的实际例子

1。创建私有变量

闭包可用于创建只能通过特定函数访问或修改的私有变量。

function createCounter() {
    let count = 0;

    return {
        increment: function() {
            count  ;
            return count;
        },
        decrement: function() {
            count--;
            return count;
        },
        getCount: function() {
            return count;
        }
    };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1
console.log(counter.getCount()); // 1

在此示例中,count是一个私有变量,只能通过increment、decrement和getCount方法访问和修改。

2.动态创建函数

闭包允许您使用特定数据动态创建函数。

function greetingGenerator(greeting) {
    return function(name) {
        return `${greeting}, ${name}!`;
    };
}

const sayHello = greetingGenerator('Hello');
const sayGoodbye = greetingGenerator('Goodbye');

console.log(sayHello('Alice')); // Hello, Alice!
console.log(sayGoodbye('Bob')); // Goodbye, Bob!

这里,greetingGenerator 使用greeting 变量创建一个闭包,允许 sayHello 和 sayGoodbye 在调用时使用它。

3.在异步代码中维护状态

闭包在异步编程中特别有用,因为您需要在代码的不同部分维护状态。

function fetchData(url) {
    let cache = {};

    return function() {
        if (cache[url]) {
            return Promise.resolve(cache[url]);
        } else {
            return fetch(url)
                .then(response => response.json())
                .then(data => {
                    cache[url] = data;
                    return data;
                });
        }
    };
}

const getUserData = fetchData('https://jsonplaceholder.typicode.com/users/1');

getUserData().then(data => console.log(data)); // Fetches data from the API
getUserData().then(data => console.log(data)); // Returns cached data

在此示例中,缓存在对 getUserData 的多次调用中进行维护,确保每个 URL 仅提取一次数据并随后重用。

结论

闭包是 JavaScript 的一项强大功能,它允许函数保留对其词法范围的访问,即使在该范围之外执行时也是如此。它们支持数据隐私、有状态函数,并且是函数式编程的基石。通过理解和使用闭包,您可以编写更高效、可读且可维护的 JavaScript 代码。

在您的项目中尝试闭包,您很快就会欣赏到它们的多功能性和强大功能。快乐编码!

版本声明 本文转载于:https://dev.to/prinxard/understanding-closures-in-javascript-a-comprehensive-guide-1ke9?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在JavaScript中声明变量时,为什么要始终使用\“ var \”?
    在JavaScript中声明变量时,为什么要始终使用\“ var \”?
    考虑以下示例:您可能希望此功能返回11;但是,由于“ varaible2 = 6”上的错别字,它返回了NAN。线。更糟糕的是,该错别字无意间创建一个全局变量,它具有拼写错误的名称“ varaible2。因此,强烈建议使用“ var”关键字,即使对于全局变量,也建议始终使用“ var”关键字来声明变...
    编程 发布于2025-02-06
  • 如何从大熊猫的大型文本数据集中有效删除标点符号?
    如何从大熊猫的大型文本数据集中有效删除标点符号?
    挑战: 这个问题在处理大型文本数据集时探索了str.replace的几种性能替代方案: 1。 REGEX.SUB:使用预编译的Regex模式从RE库中使用SUB函数。此方法对str.replace进行了重大的性能改进。 2。 str.translate:利用python的str.transla...
    编程 发布于2025-02-06
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。 To resolve this issue and ensure scripts execute on subsequent page visits, Firefox...
    编程 发布于2025-02-06
  • 我如何设计用于存储全球街道地址的最佳数据库?
    我如何设计用于存储全球街道地址的最佳数据库?
    确定全球街道地址的最佳数据库设计作为程序员,您会面临设计数据库的挑战来自世界各地。本文探讨了实现此目标的可能性,并提供了一种实用方法。 全局地址的常见数据库结构地址line(x4) 邮政编码 sub-building house/premise number 简化数据输入局部考虑[&&&&&&&...
    编程 发布于2025-02-06
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样?使用openssl?答案:可以使用mcrypt数据加密数据,可以使用openssl。关于如何使用openssl对McRypt进行加密的数据: openssl_decrypt...
    编程 发布于2025-02-06
  • 如何在Java列表中有效计算元素的发生?
    如何在Java列表中有效计算元素的发生?
    计数列表中的元素出现在列表 中,在java编程中,列举列表中列举元素出现的任务来自列表。为此,收集框架提供了全面的工具套件。在这种情况下,Batocurrences变量将保持值3,代表动物列表中的“ BAT”出现的数量。 &&& [此方法是简单的,可以得出准确的结果,使其成为计算列表中元素出现的理...
    编程 发布于2025-02-06
  • 如何有效地更新实体框架5中的记录?
    如何有效地更新实体框架5中的记录?
    [2 优化实体框架5记录更新 实体框架5提供了几种更新数据库记录的方法。 该分析比较了三种常见方法,突出了它们的优势和缺点,以帮助您选择满足需求的最佳方法。 方法1:获取并更新单个属性 允许对修改哪些属性进行精确控制。 属性排除:对于某些属性(如密码)不应通过此方法直接更新的方案。 多个查询:需要...
    编程 发布于2025-02-06
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在java中的多个返回类型:一个误解介绍,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但是,情况确实如此吗?通用方法:拆开神秘 [方法仅具有单一的返回类型。相反,它采用机制,如钻石符号“ ”。分解方法签名: :本节定义了一个通用类型参数,E。它表示该方法接受了扩展foo类的任...
    编程 发布于2025-02-06
  • 我可以在CSS中使用SVG作为伪元素吗?
    我可以在CSS中使用SVG作为伪元素吗?
    使用svgs用作pseudo-element content css content properts允许在使用元素之前或之后使用元素插入各种类型的内容伪元素,例如::之前和::之后。但是,对可以包括哪些内容有限制。可以将svgs用作pseudo-element Content?,现在可以使用s...
    编程 发布于2025-02-06
  • 在没有密码提示的情况下,如何在Ubuntu上安装MySQL?
    在没有密码提示的情况下,如何在Ubuntu上安装MySQL?
    在ubuntu 使用debconf-set-selections sudo debconf-set-selections
    编程 发布于2025-02-06
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-02-06
  • 如何从PHP服务器发送文件?
    如何从PHP服务器发送文件?
    将文件发送到user
    编程 发布于2025-02-06
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 // error:“ coss redeclare foo()” 但是,php工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地...
    编程 发布于2025-02-06
  • 您什么时候需要取消多层指针?
    您什么时候需要取消多层指针?
    使用多个级别的指针是有道理的: 在面向对象的编程上下文中,可以使用三重指针来表示复杂的指针层次结构。例如,考虑以下C类结构:类A { 民众: char *b; }; B级{ 民众: char *c; }; 在这里,A对象包含一个指向B对象的指针,而B对象包含指向char的指针。要从...
    编程 发布于2025-02-06
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    Exploiting Regular ExpressionsA more efficient solution involves leveraging regular expressions.正则表达式允许您定义复杂的搜索模式并在单个操作中执行文本转换。示例示例usage 接下来,您可以使用匹配器...
    编程 发布于2025-02-06

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3