你真的懂闭包么?

简介: 前言本文主要总结一下 到目前为止对闭包的理解.好几年之前学习闭包的时候模模糊糊,看了网上的一些帖子,理解为:函数内部可以使用函数外部的变量,后面看了你所不知道的JS,以为自己懂了,后面面试的时候又感觉自己不懂了,而今感觉自己真正懂了==,特此记录一下。

前言


本文主要总结一下 到目前为止对闭包的理解.

好几年之前学习闭包的时候模模糊糊,看了网上的一些帖子,理解为:函数内部可以使用函数外部的变量,后面看了你所不知道的JS,以为自己懂了,后面面试的时候又感觉自己不懂了,而今感觉自己真正懂了==,特此记录一下。


闭包的几个要点


MDN中是这样定义的:

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。

有点懵逼😳是吧,我来拆解为三个要点(这三个要点为重点!!!):

  • 要点1:由 一个函数 以及 其定义时所在封闭环境内的各种资源(引用)构成 的组合称为闭包
  • 要点2:函数作为返回值时,闭包一般是通过 return 把局部定义的函数"带"出去,每次"带"出去的函数都是新的函数(就是说每次返回的函数都是不一样的!!!)
  • 要点3:使用闭包后,里面的变量不会马上销毁,会一直存在栈中。


实战

对于要点1的理解,看下面这个例子

//函数作为返回值
//eg1:
function test() {
  const a = 1;
  returnfunction () {//这里的匿名函数和上面的a捆绑在一起构成了一个闭包
    console.log('a:', a);
  }
}
const fn = test();
const a = 2;
fn()//a: 1

请注意函数定义的位置!再看例2:

//函数作为参数
//eg2
function test1(fn1) {
  const b = 1;
  fn1();
}
const b = 2;
function fn1() {//这里的fn1和上面的b构成了一个闭包
  console.log('b:', b);
}
test1(fn1)//b: 2

由例1和例2可以知道,MDN中定义中的“及其捆绑的周边环境状态”中的“其”指的就是函数定义的地方;

对于要点2的理解,看下面这个例子

函数是一个静态代码块,那么多次调用外层函数返回出来的闭包函数,是同一个吗?来看看:

function test() {
    function closure() { }
    return closure;
}
const a = test();
const b = test();
console.log(a === b);   // false

意不意外,惊不惊喜??

为什么呢?

如果不能理解,看下面一行代码:

function test() {
    const a = function () { };
    const b = function () { };
    console.log(a === b);   // false
}

可以理解了么:每一次 function 都定义了一个新的函数。举个例子,一个学校里面有五个小明,但是这五个人是长相不一样的人。

对于要点3的理解,看下面这个例子

function test5() {
  var num = 0;    //s1
  function add() {//s2
    console.log(++num)
  }
  return add;
}
var add = test5();
console.log(add());//1 undefined
console.log(add());//2 undefined
console.log(add());//3 undefined
console.log(add());//4 undefined
console.log(add());//5 undefined

这里的s1处的num和s2处的add构成了闭包,并且在add执行的过程中,num并没有释放,而是一直存在栈中!


结束

再重复一遍闭包:

  • 由 一个函数 以及 其定义时所在封闭环境内的各种资源(引用)构成 的组合称为闭包
  • 函数作为返回值时,闭包一般是通过 return 把局部定义的函数"带"出去,每次"带"出去的函数都是新的函数
  • 使用闭包后,里面的变量不会马上销毁,会一直存在栈中。
目录
相关文章
Navicate如何全部选中表,点击表,然后移动到右侧,右侧可以选中,实现拖拽
Navicate如何全部选中表,点击表,然后移动到右侧,右侧可以选中,实现拖拽
|
4天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
300 116
|
19天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
7天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
480 44
Meta SAM3开源:让图像分割,听懂你的话
|
14天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
692 222
|
2天前
|
Windows
dll错误修复 ,可指定下载dll,regsvr32等
dll错误修复 ,可指定下载dll,regsvr32等
135 95