浅谈js的闭包

浅谈js中的闭包

闭包的概念

闭包是JS中的一个重要的概念,据说闭包和作用域是前端必须掌握的两样东西,但闭包对于初学JS的人来说不是一个容易理解的概念,本文分享一下自己对闭包的理解和心得,与大家一起探讨。
官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分;相信能看懂这个官方概念的人并不多,因为这句话实在是太抽象了;那么究竟什么是闭包呢?通俗的理解就是,闭包就是函数嵌套函数,能够利用内部函数的执行来读取其他外层函数(层级往上,直到window)私有变量的函数。

闭包的原理

那么闭包又有什么作用?它是怎么实现作用的呢?
闭包的作用主要有两点:
1.保护全局变量不被污染;
2.获取函数内部的变量;
在说闭包函数之前,先回顾一下js的作用域,在js里面变量的作用域包括全局作用域(即在window对象下定义的变量,全局都可以访问),块级作用域(如for循环,let,const定义的变量,只在花括号内有效),函数作用域。
我们都知道,函数作用域在函数执行完成后,变量即失效,我们无法再访问到这个变量;因为函数在执行时,在堆内存中开辟了一个执行空间(函数的赋值,运算等都在这个空间内完成),当函数执行完成后,这个空间也就自动销毁了;所以我们无法再访问到这个空间内定义的变量;但是,如果函数的返回值是一个函数,或者返回值是一个复杂数据类型,而在这个复杂数据类型中会用到函数里面定义的变量,并且在函数外部有一个变量接收这个返回值,那么这个执行区域就会一直保留在堆内存中,直到外部的变量不再接收这个返回值,这就是说,我们仍然可以通过执行接收到的返回值,来访问到外层函数的执行空间,从而获取外层函数的私有变量,这就是闭包的原理。

闭包的作用及用途

我们用几段简单的代码来辅助说明一下闭包函数的作用;

<script>
function fn1() {
var a = 10;
console.log(a);
}
fn1();           //10
console.log(a); //undefined
</script>`

这个结果相信大家不会有什么异议,普通函数作用域内定义的变量用完即失效,所以第二个结果为undefined;接下来把代码稍作更改:

<script>
function fn1() {
var a = 10;
console.log(a);
return function () {
console.log(a)
}
}
var res = fn1();     //10
res();                //10
</script>

这段代码就形成了一个闭包函数,如上,它会打印出两个10;第二个10,就是通过执行内嵌的函数来访问fn1的私有变量;即闭包函数的功能之一,它可以访问到函数的内部变量。

我们再来看下面这段代码

var a = 10;
function Add3() {
var a = 10;
return function () {
a++;
return a;
};
};
var cc = Add3();
console.log(cc());
console.log(cc());
console.log(cc());
console.log(a);

上面这段函数打印结果为11,12,13,10
代码运行过程为:Add函数外面定义一个变量接收其返回值,即var cc = function(){
a++;
return a;
}
然后执行函数cc();cc函数自己没有变量a,于是就往上层找,找到在add函数中定义的a拿过去使用,代码运行a++;接着继续调用,重复上面的操作,这就实现了私有变量的递增;但是对于定义在全局的a的值是没有改变的;即不会影响其他代码使用全局变量a的结果,这就保护了全局变量不被污染。

我们接着往下再看这段代码

function fn(i) {
return function (n) {
console.log(n + (--i))
}
}

var f = fn(2)
f(3)        //4
fn(4)(5)   //8
fn(6)(7)   //12
f(8)       //8

对于这段代码的运行结果,相信很多初学者会感到迷惑;下面我把代码的运行过程解析一下。
因为执行fn(4),fn(6)时在函数外部没有值接收,所以没有形成闭包函数,fn函数执行两次,开辟两个执行空间,且执行完成就失效,所以他们的变量不会关联,而fn(2)执行时,返回的函数被外部的变量f接收,形成了闭包,fn的执行空间会被保存,所以在执行f(3),f(8)时,都访问了fn的私有变量(附下图以便直观理解)。
在这里插入图片描述

通过上面几个实例,总结一下形成闭包的条件:(假设A函数嵌套B函数)
【1】B函数内访问了A函数的变量;
【2】函数嵌套;
【3】B函数在A函数的外部被调用
三个条件缺一不可。

闭包函数的缺点:

从闭包函数的原理我们得知,闭包函数之所以可以访问函数的内部私有变量,其原因在于在堆内存中开辟了一个不会销毁的执行空间,那么如果存在很多闭包函数,就会大量消耗计算机的内存,会造成网页的性能问题,当内存占满后,就会导致数据泄露。

以上就是本人对于闭包函数的一点心得,希望能有助于初学js的朋友理解闭包,因我本人也是初学小菜鸟,所以文中若存在错误和不足还望大佬们不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值