JS:闭包

本文深入探讨JavaScript中的闭包概念及其应用场景,包括如何利用闭包实现变量公有、缓存管理、封装及模块化开发等。同时,还介绍了闭包可能导致的内存泄漏问题。
闭包
在了解闭包之前,来点【作用域】以及【作用域链】。如果你知道请跳过这弱鸡的一段。
作用域链:[[scope]]中所存储的【执行期上下文】对象的集合,这个集合呈链式链接,我们把这个链式链接叫做作用链接。
一段没什么用话
[[scope]](隐式属性):仅供JS引擎自己存取,[[scope]]指的就是作用域,其中存储了运行期上下文的集合。
执行期上下文:函数执行时对应的执行上下文都是独一无二的,当函数执行完毕,它所产生的执行上下文被销毁。
function a(){
    function b(){
        ...
    }
}
var glob=100;
a();
复制代码
作用链解析
a的函数被定义:a.[[scope]]-->0:GO{}
a被执行: a.[[scope]]-->0:a.AO{}
                       1:GO{}
b函数被定义:b.[[scope]]-->0:a.AO{}
                         1:GO{}
b被执行:   b.[[scope]]-->0:b.AO {}
                         1:a.AO {}
                         2:GO{}
*查找变量:从作用域链的顶端依次向下查找。
复制代码
【闭包】是一个函数外加上该函数创建时建立的作用域。也就是说当一个内部函数被保存到外部,将生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
function a(){
    var num = 100;
    function b(){
        num ++;
        console.log(num);
    }
    return b;
}
var demo = a();
//将函数a 的返回值(函数b)赋值给一个变量。把函数b保存到了外部。
demo();//101
demo();//102
复制代码
闭包解析
a的函数被定义:a.[[scope]]-->0:GO{}
【第1个demo()执行】
a被执行: a.[[scope]]-->0:a.AO{num:100}
                       1:GO{}
b函数被定义:b.[[scope]]-->0:a.AO{num:100}
                         1:GO{}
b被执行:   b.[[scope]]-->0:b.AO {num:101}
                         1:a.AO {num:101}
                         2:GO{}
demo()执行后 b.AO {}被销毁
            a.AO{num : 101}不释放
【第2个demo()执行】
a被执行: a.[[scope]]-->0:a.AO{num:101}
                       1:GO{}
b函数被定义:b.[[scope]]-->0:a.AO{num:101}
                         1:GO{}
b被执行:   b.[[scope]]-->0:b.AO {num:102}
                         1:a.AO {num:102}
                         2:GO{}
demo()执行后 b.AO {}被销毁
            a.AO{num : 102}不释放
...(以此类推)
复制代码
闭包的作用
1.实现公有变量;
2.可以做缓存(存储结构);
3.可以实现封装、属性私有化;
4.模块化开发,防止污染全局变量。
复制代码

1) 实现公有变量 -- 例子:累加器

function accumulator(){
    var count = 0;
    function add(){
        count ++;
        console.log(count);
    }
    return add;
}
var counter = accumulator();
counter();//1
counter();//2
复制代码

2) 可以做缓存 -- 例子:签到

function signIn(){
    var who = "";
    var obj = {
        check : function (){
            if(who == ""){
                console.log( "You've already signed it");
            }else{
                console.log( who + " finished the check-in");
                who = "";
            }
        },
        person : function (name){
            who = name;
        }
    }
    return obj;
}
var signed = signIn();
signed.person('kiwi');
signed.check(); //kiwi finished the check-in
signed.check(); //You've already signed it
复制代码

3) 可以实现封装、属性私有化
4) 模块化开发,防止污染全局变量

var name = "coco";
var init = (function () {
    var name = "kiwi";
    function callName() {
        console.log(name);
    }
    return function () {
       callName();
    }
}());
init();//kiwi
复制代码

这是一篇凑不要脸的整理,可能有错且不全面!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值