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

yizhihongxing

一文搞懂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 是什么意思

    JavaScript 是一种高级的、弱类型的编程语言,经常用于 Web 前端开发以及服务器端开发。它被设计成一种脚本语言,可以在 Web 页面上直接嵌入 HTML 代码中,也可以在服务器上运行。JavaScript 使得 Web 页面变得更加动态化和交互式。 JavaScript 的语法类似于其他编程语言,如 C、Python 和 Java。它支持基本的数据…

    JavaScript 2023年5月17日
    00
  • Cookies的各方面知识(基础/高级)深度了解

    下面我为大家讲解关于”Cookies的各方面知识(基础/高级)深度了解”的完整攻略。 1. 基础知识 1.1 Cookies 是什么? Cookies 是一种小型文本文件,可以保存在访问者的计算机上。当用户访问了某个网站时,该网站会将 Cookies 文件发送到用户的计算机并存储在用户的浏览器中。这里需要注意,Cookies 是被网站发送到用户计算机并存储的…

    JavaScript 2023年6月11日
    00
  • JavaScript实现的in_array函数

    下面是关于“JavaScript实现的in_array函数”的完整攻略。 1. 了解in_array函数的作用 ‘in_array’函数可以判断一个元素是否在一个数组中。如果在,返回true,否则返回false。 2. 实现in_array函数 JavaScript中没有内置的in_array函数,但是可以使用一些简单的方法实现。 2.1 方法一:使用ind…

    JavaScript 2023年5月27日
    00
  • 一个简单的网站访问JS计数器 刷新1次加1次访问

    实现一个简单的网站访问计数器可以通过 JavaScript 来完成。我们需要在网站的页面中添加一个计数器的容器,然后通过 JavaScript 代码来动态修改这个容器中的数值即可。 以下是实现这个计数器的一些步骤: 1. 建立计数器的容器 我们需要创建一个 HTML 元素来表示这个计数器的容器,并且给它一个初始值。例如,在一个网站主页中,我们可以添加一个 &…

    JavaScript 2023年6月11日
    00
  • JavaScript实现获取最近7天的日期的方法详解

    JavaScript实现获取最近7天的日期的方法详解 介绍 在Web前端开发中,获取最近7天的日期是很常见的需求。本文将提供几种实现方法,包括原生JavaScript和Moment.js库的使用方法。 实现方法一:原生JavaScript 方法一:获取当前日期并递减7天 通过使用Javascript内置的Date对象,我们可以获取现在的日期,并通过设定日期对…

    JavaScript 2023年5月27日
    00
  • ECharts transform数据转换和dataZoom在项目中使用

    ECharts transform数据转换和dataZoom在项目中使用是数据可视化中非常重要的一部分,本文将会从以下几个方面来进行讲解: transform数据转换的基本概念及使用方法 示例说明transform数据转换的用法 dataZoom使用方法及示例 1. transform数据转换的基本概念及使用方法 在ECharts中,数据转换是一种通过对数据…

    JavaScript 2023年6月10日
    00
  • 详解JavaScript中var和let的区别

    详解JavaScript中var和let的区别 1. var的作用域 在ES5及其之前的版本中,我们通常使用var声明变量。在使用var声明变量时,需要注意变量的作用域。 全局作用域 当在函数外使用var声明变量时,该变量为全局变量,即便在函数内部使用,它也可以被访问到。例如: var a = 1; function test() { console.log…

    JavaScript 2023年6月10日
    00
  • 十代酷睿的性能差异 i9-10900K/i7-10700K/i5-10600K性能对比

    十代酷睿的性能差异 i9-10900K/i7-10700K/i5-10600K性能对比 随着十代酷睿处理器的推出,消费者可以选择 i9-10900K、i7-10700K、i5-10600K 等不同的处理器型号。这些处理器具有不同的性能和价格,本文将详细讲解它们之间的性能差异。 i9-10900K i9-10900K 是十代酷睿处理器中最高端的型号,采用了 L…

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