JS闭包知识点整理

JS闭包这是一个术语,但是用通俗的解释就是函数里的函数!
这是一个相当麻烦的概念,所以我有些不知道从哪里整理,真是无语。
还是循序渐进的弄吧!

函数的作用域(scope)

作用域确定了函数的变量访问权限:

 function test() {
      var a = 4;
 }
 test();
 alert(a);
 //报错:a is undefined a没有被定义

这是一个很简单的定义域问题,函数外部不能通过test()方法之外的函数访问函数内部的局部变量。
对程序进行一下小小的修改:

function test() {
      a = 4;//此时a是一个全局变量
 }
 test();
 alert(a);
 //成功:4

这是因为a变成一个全局变量,所以在程序任何地方都可以访问。
简单的理解一下执行流程:
基础:GC(垃圾回收器)当当前对象不在被引用,GC会回收当前对象。
1>调用test函数,内存为函数的变量和代码分配空间,a=4,执行完成。
2>test执行完后不再被引用,包括a;所以被GC回收。
3>alert函数引用a,因为函数内部变量a已被回收,内存中不存在a指向的引用地址。此时会出错,提示a is undefined.

闭包的最简创建:

 function test() {
            a = 4;
            function inner() {
                a++;
            }
            return inner;
        }
        var inn =test();
        inn();
        alert(a);

上述函数test里面还有一个函数,这个函数叫内部函数。他可以看成内部的变量,这个函数可以访问test函数中的变量a;
1>函数test创建,内存为它分配空间。包括inner函数和变量a;
2>函数test执行,为a和函数inner分配空间,然后对按照声明顺序。
将a初始化为4,inner只分配了空间,没有被执行。
3>将函数inner返回给了全局变量。
4>此时我们除了函数inner之外,没有任何方法访问并修改函数test中a的值。
5>执行函数inn实际就是inner函数,对a进行+1;
6>执行完毕,此时GC回收该全局变量inn或说inner函数。(inn在这里是个引用)
下面用更术语的方法解释闭包,还是原来的那串代码:
闭包:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
…初学的话看懂就怪了…真是无语;
我的理解:
通过上述的过程,你应该知道闭包其实是大包套一个小包,而小包可以通过将自己的引用赋给全局变量inn来改变大包中a的值。
那么闭包我就可以这样理解:该包提供了一个全局变量的引用,这个引用就是指向闭包中许多变量(就是test和inner中的一系列变量),通过这个引用我们可以访问这些变量;

PS:e…这个说法是个人见解,日后不对会做修改;
代码执行流程的内存分析(进阶分析简略):
为什么我们还可以在test执行后,访问a,并不是GC回收test,然后创建了inn的函数包含test所有变量。这样是不合理的,显然这会增加系统的开销!而是在函数test在未执行完inn()根本就没有被GC回收。而是继续保存在内存中。

标准解释:

网上搜了很多,整理一下,对闭包进行进阶解释:
首先引入几个概念:
(我承认这些概念很恶心,理解了会很有用,就比如说再次提到函数内部有一个函数时,就可说闭包,这节省交流效率,但同时也会增加交流难度。)
作用域链:全局变量或全局函数的作用域链是window对象,作用域链就是父关系,通过他的上一级对象访问此对象;
执行环境:这个就是对test进行作用域的设定和后置活动对象的设定。这是js解释器将作用域链解释为执行环境,可以理解为进行激活。
活动对象
活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。
test活动对象位于test作用域链中的最顶端。
活动对象的设定:包括函数的一些个形参,保存调用test时的参数值,
这些被保存在活动对象的arguments属性中。

执行流程(闭包)

  1. 执行函数test,然后内存为其分配空间。
  2. 分配空间中的细节:
    1>js解释器test作用域链解释为执行环境
    2>初始化test中变量的作用域
    3>创建一个test活动对象,用于保存调用test实参值,(本例无),
    将活动对象保存在test作用域的顶端。
    4>内置函数inner执行同样的上述3个流程。
  3. 通过引用保存函数inner引用,此时test函数中的变量并没有被GC回收,访问a值成功
  4. 弹出窗口:5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值