JS 闭包

本文深入探讨JavaScript中的闭包概念,解释了为何外部无法直接访问函数内部变量以及如何利用闭包解决这一问题。通过实例展示了闭包允许外部访问内部变量的原理,并指出闭包可能导致的内存泄漏问题。同时,文章通过一道题目分析了闭包在函数调用过程中的作用,强调了闭包在防止变量污染和封装组件时的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念

什么是闭包?

一个函数和它周围状态的引用捆绑在一起的组合

听到这句话可能有的小伙伴有点难以理解,那么你也可以理解成

函数嵌套函数,内部函数就是闭包

闭包应用

在了解到闭包的概念后,我们带着闭包的概念来对闭包进行探讨

function f() {
  let  a = 10
}
console.log(a)

我们在js中设置这样的一串代码,设置一个函数,在函数内部定义一个变量a,我们想通过外部来访问函数的内部变量a,我们会发现控制台给我们报错了

这是为什么呢?那是因为函数存在作用域,在函数作用域内,内部可以读取外部变量,但外部不可以读取内部变量, 所以我们在全局中调用函数内部的变量的时候就肯定会报错,那我们要如何解决这个问题呢?所以我们就要引入闭包来解决这个问题,我们把上面的代码进行改装一下

function Out() {
  let  a = 10
  return function () {
    console.log(a)
  }
}
var foo = Out()
foo()

我们执行这串代码我们就发现了,我们可以访问到函数的内部变量a了,因为我们在out函数内部返回一个函数,在返回的函数中我们去调用局变量a,由于返回的函数中没有变量a,所以它会通过作用域链,在我们定义函数的地方向上级进行查找,此时再将我们调用out函数赋值给foo,那么此时foo其实就是等于out函数return出来的函数,即

 foo = function () {
  console.log(a)
  }

然后我们再去调用foo函数,即调用eturn出来的函数,这样我们就可以拿到函数内部的变量a了,通过这个例子我们就发现了通过闭包,外部可以访问到函数内部的变量了.

在这里可能就有小伙伴就会问了,当返回的函数内部没有a时,为什么他会向在定义的时候查找,而不是调用的时候查找呢?

这个时候我们就要回到闭包的概念上:一个函数和它周围的状态引用绑定在一起的组合

我们理解这句话的时候就会发现,返回的函数它周围的状态引用就是out中定义的a绑定在一起,所以当返回函数内部没有a的时候,他会向在定义的时候向上级查找。

在这串代码的演示中,可能就有小伙伴还会有一个疑问,当一个函数调用完成后,其内部的变量不是会被销毁吗,为什么调用完out函数后,内部函数还能访问到变量a呢?

在这里我们就要引入闭包重要的一个特征了,即:内部函数没有执行完成,外部函数的变量就不会进行销毁

因为闭包这条重要的特征所以我们就能够访问到变量a。

虽然说闭包的特性给予了我们很多的方便,但他也有一个存在的缺点,假如我们经常去调用一个闭包函数,那么外部函数的变量就不会销毁,那么他就会一直储存在我们的内存中,不能被释放出来,那么就会造成内存泄漏。

通过上面的对闭包的理解过后我们思考一道这样的题

function f() {
let a = 10
  f1()
}
let a = 20
function f1() {
console.log(a)
}
f()

请问图中的最终输出的结果是多少?

我们拿到这道题后我们先进行分析,我们调用f函数,首先是我们先进入f函数,我们发现f函数里面定义了一个变量a,然后调用了f1函数,那么我们就可以发现这个其实就是函数嵌套函数,这就是一个闭包函数,那我们继续分析,我们进入到f1函数中我们发现在内部调用了console.log的方法,那么现在我们就要去找变量a的值是多少,由于闭包的概念:一个函数和它周围的状态引用绑定在一起的组合,所以我们就要在f1定义的地方去进行查找,然后再向上级查找,我们发现f1上级就是全局作用域,此时a就等于20,所以在我们的最终结果就是20

在我们的实际开放中我们为了防止变量的污染,我们在封装组件的时候经常会应用闭包来解决很多的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值