一文搞懂JavaScript中最难理解概念之一的闭包

一文搞懂JavaScript中最难理解概念之一的闭包

闭包(closure)在 JavaScript 中是一个非常重要的概念,也是最难理解的。本文将详细解释什么是闭包、为什么需要闭包以及闭包有哪些特点。同时,给出两个简单的闭包示例,帮助你更好地理解闭包。

什么是闭包?

在最简单的形式下,闭包是一个词法作用域内,能够引用自由变量的函数。

这里需要解释一下自由变量。自由变量指的是在函数中使用的变量,但不是函数的参数也不是函数内部声明的变量。例如:

function add(x) {
  return x + y;
}

在这个函数中,x 是一个参数,而 y 是一个自由变量。

如果一个函数可以访问到其他函数的作用域中的变量,那么这个函数就被称为闭包。在内部函数可以访问到外部函数定义的变量时,就形成了闭包。

为什么需要闭包?

使用闭包,可以使变量不被释放,搭配IIFE可以实现模块化的代码结构,增加代码的可读性和可维护性。

另外,闭包还可以用于解决作用域相关的问题。在 JS 中函数作用域是静态的,意味着变量在声明的时候就分配了内存空间,而不是在执行的时候。所以,变量的作用域就是在函数父级作用域的整个生命周期中,而不是在函数执行完毕后立即销毁。

闭包的特点

闭包有以下特点:

  1. 闭包可以访问它们所包含的函数中的变量。

  2. 一般来说,一个函数返回之后,局部变量就会被释放,但闭包不同。闭包内部保留了对外部环境的引用,当外部环境变量被修改后,闭包获得的变量值也会跟着改变。

  3. 当函数被调用时,每次都会生成一个新的闭包。

例子一:计数器

第一个示例是一个计数器,需要一个函数来返回另外一个函数,由此创建一个计数器。每次调用返回的函数都会增加计数器的值。

function counter() {
  let count = 0;
  return function () {
    count++;
    console.log(count);
  };
}

const c = counter();

c(); // 1
c(); // 2
c(); // 3

在这个例子中,返回的函数可以访问外部闭包中的变量 count,每一次调用返回的函数,因为可以访问外部环境中的变量,所以可以持续记录 count 的值。

例子二:模块化的代码结构

第二个示例中,用闭包实现模块化的代码结构。这个模块包含了两个函数:一个用来设置一个计数器的初始值,另一个用来给这个计数器增加值。

const counter = (function () {
  let count = 0;

  function changeCount(val) {
    count += val;
  }

  function setCount(val) {
    count = val;
  }

  function getCount() {
    return count;
  }

  return {
    change: changeCount,
    set: setCount,
    get: getCount,
  };
})();

counter.set(10);
counter.change(5);
console.log(counter.get()); // 15

在这个例子中,定义了一个 IIFE,函数体内有几个变量(这里仅有 count),以及多个能够访问这些变量的函数。这些函数被返回并成为 counter 对象的属性,由此创建了一个模块。由于变量 count 不会被释放,多次调用 counter 的方法将持续记录 count 的值。

结论

闭包是 JavaScript 中非常重要但又难以理解的概念。了解闭包能够帮助我们在编写代码时更好地控制数据的作用域和可访问性,这样就可以有效提高代码的可读性和可维护性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文搞懂JavaScript中最难理解概念之一的闭包 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • JavaScript DOM 添加事件

    JavaScript DOM 添加事件的完整攻略如下: 1. 确认要添加事件的HTML元素 在JavaScript中,我们首先需要确认要给哪个HTML元素添加事件。这个HTML元素可以是任何一个有效的DOM元素,比如一个按钮,一个输入框,一个复选框等等。我们可以使用DOM选择器(getElementById()、querySelector()等)去获取这个H…

    JavaScript 2023年6月10日
    00
  • vue 弹窗时 监听手机返回键关闭弹窗功能(页面不跳转)

    实现Vue弹窗时,监听手机返回键关闭弹窗功能可以通过以下步骤完成: 在弹窗组件中,监听手机返回键的按下事件,如果弹窗处于打开状态,则关闭弹窗,否则执行默认的页面返回事件。具体代码如下: <template> <div> <button @click="openModal">打开弹窗</button…

    JavaScript 2023年6月11日
    00
  • Javascript 函数的四种调用模式

    Javascript 函数可以通过四种不同的方式进行调用,每种调用方式都有对应的特点和使用场景,下面详细介绍一下这四种调用模式。 1. 函数调用模式 函数调用模式是最简单的调用方式,也是最常见的方式。我们可以直接调用一个函数,例如: function greet(name) { console.log(‘Hello, ‘ + name); } greet(‘…

    JavaScript 2023年5月27日
    00
  • JS 实现倒计时数字时钟效果【附实例代码】

    JS 实现倒计时数字时钟效果是一个比较常见的前端特效,本文将为大家分享如何实现这个效果并附上实例代码。以下是完整攻略: 第一步:HTML 基础 首先,我们需要在 HTML 中创建一个数字时钟展示区域,可以选择一个 div 包含一个 h1 标签或者直接使用 h1 标签。具体代码如下: <div id="countdown-clock"…

    JavaScript 2023年5月27日
    00
  • JS异步代码单元测试之神奇的Promise

    JS异步代码单元测试一直是开发人员要面对的挑战。为了解决这个问题,Promise异步编程模式被引入到JavaScript中,因其简单、灵活和可重用性而受到广泛认可。在本攻略中,我们将深入探讨如何在单元测试中使用Promise,以及如何跟踪异步代码逻辑和处理可能的异步回调。 异步单元测试面临的问题 在传统的单元测试中,我们可以通过直接调用函数、对函数输出结果进…

    JavaScript 2023年5月28日
    00
  • 正则表达式练习器

    正则表达式练习器是一款可以帮助用户练习正则表达式基础知识和技能的在线工具。下面是针对这款工具的完整攻略: 注册和登录 访问正则表达式练习器的网站,点击浏览器页面上方的“注册”按钮,填写注册表单并提交。用户名和密码必须至少包含一个数字和一个大写字母,密码长度至少为8个字符。注册成功后,你可以使用注册的用户名和密码进行登录。 访问正则表达式练习器的网站,点击浏览…

    JavaScript 2023年6月11日
    00
  • JavaScript操作选择对象的简单实例

    下面我将为您详细讲解“JavaScript操作选择对象的简单实例”的完整攻略。 1. 选择对象 要操作 HTML 中的元素,我们必须首先找到它。找到元素的最常用方法是使用 id 属性。我们可以使用 document.getElementById() 方法来选择一个有 id 的元素。 比如,我们有如下HTML代码: <div id="demo&…

    JavaScript 2023年5月27日
    00
  • json格式的时间显示为正常年月日的方法

    为了让JSON格式的时间显示为正常的年月日,我们可以使用JavaScript内置的Date对象和其中的一些方法。下面是具体的攻略: 首先,我们需要获取JSON格式的时间,并将其转化为JavaScript的Date对象。假设我们的JSON格式时间为2022-05-12T10:30:00Z,则可以使用以下代码将其转化为Date对象: javascript con…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部