千家信息网

怎样理解JavaScript 闭包

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,怎样理解JavaScript 闭包,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。深入剖析 JavaScript 闭包什么是闭包?❝一个函
千家信息网最后更新 2026年11月02日怎样理解JavaScript 闭包

怎样理解JavaScript 闭包,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

深入剖析 JavaScript 闭包

什么是闭包?
❝

一个函数和对其周围状态的引用捆绑在一起,这样的组合就是「闭包」.

通俗的说:一个内层函数可以访问外层函数的作用域 就叫 「闭包」。

在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

闭包的形成与变量的作用域以及变量的生命周期密切相关。
❞

闭包的特性

❝
  1. 函数嵌套函数

  2. 函数内部可以引用外部的参数和变量

  3. 参数和变量不会被垃圾回收机制回收

❞

闭包的优缺点

❝

优点:

❝

可以设计私有的方法和变量

❞

「缺点」

❝

常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

❞

「一般函数执行完毕后,局部活动对象就被销毁,内存中仅仅保存全局作用域。」

❞

关于 变量

变量的作用域
❝

变量的作用域:变量的有效范围。

在实际开发中,我们经常遇到的是 「函数中声明的变量作用域。」

❞
var a = '闭包';

function getValue(){
var a = '函数局部作用域'
console.log(a)
}

getValue() //函数局部作用域

❝

当在全局声明了一个同名变量,在函数内部也声明了一个同名变量,函数优先访问函数作用域中的变量。

❞
函数作用域
❝

函数作用域:在函数内部可以访问到函数外部变量,而在函数外部的变量不可以访问函数内部的变量。

为什么呢?

「因为当在函数中搜索一个变量的时候,如果函数内部没有这个变量的声明,那么它会随着代码的执行环境创建的作用域往外层逐层搜索,直到搜索到全局变量为止。」

变量的搜索是从内到外搜索的。

❞
function getData() {
var str = "闭包练习";
var fun = function(){
var innerStr = '内部变量'
}
console.log(innerStr)
//innerStr is not defined 函数外层是访问不到 函数内层变量的
}
getData()
变量的生存周期
❝

对于 「全局变量」,它的生存周期是永久的的,除非主动销毁变量。

而对于 「函数局部变量」 ,当函数执行完毕,局部变量也就销毁了。

❞
栗子 1







Document



1

2

3

4






❝

给每个 div 增加点击事件,当点击 div 时,弹出它对应的索引值。

现在无论点击哪个 div ,它 弹出的 都是 4 。

为什么呢?

「因为 div 点击事件 是被 异步触发的,当事件被触发的时候,循环已经执行完,此时的 i 的 变量值 为 4。」

如何解决 点击每个div 弹出对应的i 值呢 ?

**可以借用 闭包, 把每次循环的 i 保存起来,当执行点击事件时,它会从内到外 搜索变量的作用域,它会优先搜索到 闭包环境环境的 i **

❞
 # 闭包解决办法   

栗子 2
var num = 1;
function getValue(){
var num = 0;
return function(){
num++
console.log(num)
}
}

var s = getValue()
s()
s()
// 1 2
❝

按常理思路来:函数执行完毕,num = 1 销毁,变为初始值 num = 0 ,变量在函数中作用域从内到外逐层搜索。

前面也说到了,当函数执行完,局部变量也跟着销毁了,那为什么会 输出 2 呢 ?

❝

这里 涉及到 垃圾回收机制引用计数问题

[关于垃圾回收] https://blog.csdn.net/zhouziyu2011/article/details/61201613

简述:

「当声明了一个变量并将一个引用类型值赋给该变量时,则该值的引用次数就是1;如果同一个值又被赋给另一个变量,则该值的引用次数加1;如果包含对该值引用的变量又取得了另外一个值,则该值的引用次数减1。当该值的引用次数变为0时,则可以回收其占用的内存空间。当垃圾回收器下一次运行时,就会释放那些引用次数为0的值所占用的内存。」

❞

「解答」

❝

第一次执行 s() 时,num = 1

第二次 执行 s() 时, 由于 引用的时第一次 s () 的变量num=1,num 没有被销毁,固然在 num = 1 的基础上 再 加 1 。

❞

「注意」

如果没有使用同样引用的话,那么多次调用,都是同样的值,因为没有记录引用值。

函数在执行完毕,num = 1 被销毁掉了,初始为 0

❞
var num = 1;
function getValue(){
var num = 0;
return function(){
num++
console.log(num)
}
}

getValue()()
getValue()()
// 0 0

????闭包的作用

❝

闭包的注意作用为这两项:

  1. 「可以读取函数内部的变量」
  2. 「可以变量的值始终保持在内存中」
❞
栗子
function f2(){
let num = 0;
addNum = function(){
num++
}
function f3(){
console.log(num)
}
return f3
}

var a = f2()
a()
addNum()
a()
// 0 1
❝

结果为 0 1

函数在执行完毕,局部变量也跟着销毁, 结果 不应该是 0 0 吗 ?

其实a() 相当于 是 f3() 的闭包函数,它被执行了两次。

  • 第一次 执行 a() 时, 结果为 0 , 很好理解。
  • 第二次 执行的 f2() 函数内部的 addNum 函数,发现没这个匿名函数赋值给一个变量,而且这个变量没加 var / let , 那么它此时的作用域为 全局 ,保存在内存当中。执行 addNum 时它访问的 f2() 函数内部的局部变量 num , 此时, addNum 的存在依赖于 f2,因此 f2 也在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
  • 第三次 执行 a() 时, 因为 num 已存在内存中,而 值为1

最终输出结果:0 , 1

❞


闭包注意
  1. 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  2. 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
❞

看完上述内容,你们掌握怎样理解JavaScript 闭包的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

变量 函数 闭包 作用 内存 局部 搜索 全局 垃圾 方法 次数 事件 结果 问题 周期 外层 机制 环境 第一次 栗子 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技园 互联网科技公司排名 深圳市人人互联网科技有限公司 百单网互联网科技有限公司怎么样 广州百单互联网科技有限公司 互联网的科技 杭州互联网科技公司 小马过河互联网科技 互联网科技咨询 央行互联网金融科技公司 乌鲁木齐新华智原互联网科技学校 企晟互联网信息科技有限公司 保险科技服务互联网营销体系 互联网企业科技类企业如何做账 互联网科技资金流入 互联网科技融合创新 银川新华互联网科技学校是国营吗 科技和互联网行业的特点 互联网科技大会大佬 广东猫王互联网科技有限公司电话 科技和互联网公司 科技互联网技术 上海互联网科技有限公司 天扬科技互联网广告 互联网之后的科技是什么 华夏互联网科技业 互联网科技创新的路径 群盈汇互联网科技有限公司 智帮互联网科技公司最近动向 保山互联网科技靠谱吗
0