关于闭包和js运行机制的一点见解

一、学习背景

       肯定很多人学习js的过程中对闭包的了解一直处于懵懵懂懂的状态,对于闭包只是简单的了解“声明在一个函数中的函数,叫做闭包函数”,其实并不能很好的去理解他。这里已js运行的机制出发,深入探讨一下闭包产生的原因

二、闭包的概念

  这里引用百度百科的解释:

 简单的理解就是:声明在一个函数中的函数,叫做闭包函数。

三、闭包的特点

1.让外部访问函数内部变量成为可能;

2.局部变量会常驻在内存中;

3.可以避免使用全局变量,防止全局变量污染;

4.会造成内存泄漏(有一块内存空间被长期占用,而不被释放)

四、闭包的形成

        

 深入了解闭包需要扎实的js基础。这是一段经典的闭包代码。首先定义一个funA函数,内部返回一个匿名函数。然后将funA函数赋值给变量b,这里b其实已经是funA函数的返回值,也就是匿名函数;然后执行b函数(这里其实也就是执行了funA函数里的匿名函数)。匿名函数是打印出一个变量a,对应的就是10这个值。

五、深入思考

是什么js的运行机制导致了这种情况?

这里涉及俩个概念 预编译产生的作用域 js的垃圾回收机制

1.预编译产生的作用域

第一作用域问题分为    局部作用域(Activation Object 局部作用域)和    全局作用域(Global Object 全局作用域),也就是常说的GO和AO。

 GO执行过程

1.寻找变量声明
2.寻找函数声明并赋值
3.执行

上面的代码中首先找到a变量,(注意:这里是使用的var声明的,所以会有变量提示,但是赋值不提升,但在GO的执行过程中,会首先寻找变量声明,所以不管是let和const都是优先级最高的);此时的a变量会提升但赋值不提升所以是undefined,然后去寻找函数声明并赋值,这里又定义了一个a函数,所以此时GO中的a其实已经有值了,是一个a函数,最后js执行赋值操作将1赋值给a,此时var a = 1 ;这里也可以理解为什么函数声明优先级高于变量声明。所以在GO中变量a的赋值过程是   undefined  => function a()  =>  1。

综上所述,那么第一次打印a是a函数,第二次是1

 AO的执行过程

当一个方法被 调用 的时候(执行之前)会形成一个局部作用域AO

1. 寻找形参和变量声明
2. 实参值赋值给形参
3. 找函数声明,赋值
4. 执行

 正是因为AO和GO产生的作用域链,导致函数销毁后外部仍有访问内部变量的地址,然后又因为js的回收机制,有引用或者标记的情况下,不会回收。所以这俩大特性产生了闭包。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值