JS闭包的构成

一、作用域

作用域即变量和函数的可访问范围,也就是说作用域控制着变量和函数的可见性和生命周期

JavaScript的作用域分为全局作用域和局部作用域

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问

调用函数时,所有在函数内声明的变量名称都将被加入到作用域中


二、作用域链

作用域链详情参考链接

简单来说就是:变量访问,先在局部查找,找不到便会去局部外的局部找,再找不到就会去全局找

作用域链直接导致:在函数内部可以访问函数外部的变量,而函数外部却无法访问函数内部的变量


三、闭包的概念

闭包 实现了函数外部对函数内部变量的访问


四、闭包的构成

示例1:

// 在fun1外如何访问其内部变量a ?

function fun1() {
    var a = 0;

    function fun2() {
        a++;
        return a;
    }

    return fun2;
}

function main() {
    var f2 = new fun1();
    console.info("fun1.a is " + f2());
    console.info("fun1.a is " + f2());
}

运行 main 函数,控制台输出结果:

fun1.a is 1

fun1.a is 2


闭包的构成条件:

1、函数内部声明函数,为方便起见,称之为“外部函数”、“内部函数”

2、内部函数要调用外部函数的局部变量并返回

3、内部函数作为外部函数的返回值返回

符合这些条件后即可在外部函数的外部访问外部函数的局部变量


四、闭包的特点

示例2:

// 在fun1外如何访问其内部变量a ?

function fun1() {
    var a = 0;

    function fun2() {
        a++;
        return a;
    }

    return fun2;
}

var f2 = null;

function main() {
    console.info("run main..");

    if (f2 == null) {
        f2 = new fun1();
    }
    console.info("fun1.a is " + f2());
    console.info("fun1.a is " + f2());
}



使用html按钮触发 main 函数,点击2次,控制台输出结果:

run main..
fun1.a is 1
fun1.a is 2

run main..
fun1.a is 3
fun1.a is 4


运行结果显示变量 a 在 main 函数返回后依然驻停在内存中而不被销毁

原因:变量 f2 是全局变量,本身是驻停内存的,f2 是函数 fun1 的返回值,即函数 fun2 本身,函数 fun2 对变量 a 存在调用

通过这种层层引用的方式,迫使 局部变量 a 持续驻停内存


总结:

1、闭包可以实现函数外部对内部变量的访问

2、闭包可以实现变量的长时的内存驻停(可以实现缓存功能)

注意:闭包增加内存开销,影响网页性能,使用不当容易导致内存泄漏


四、闭包的理解

我们类比Java类对象来看JS闭包概念:

如果把外部函数看作对象,局部变量则类似于成员变量,内部函数则类似于有参构造函数

Java对象被new 出来,只要不销毁该对象本身,其成员变量和内部函数相应的也始终驻停内存

同理 就比较好理解 闭包概念


五、闭包的应用

1、迭代器或生成器

代码有空补充。。参考链接

2、大变量的缓存

3、秒杀倒计时

4、模拟实现类与继承

链接


参考资料

【1】《深入理解JS闭包》,链接

【2】《一分钟理解JS闭包》,链接

【3】《闭包的常见应用》,链接

【4】《Python的函数》,链接



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值