闭包(基础)

让我们先来看一个简单的例子

function test1() {
    function test2() {
        var b = 2;
        console.log(a);
    }
    var a = 1;
    return test2();
}
var c = 3;
var test3 = test1();
test3();

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

尽管此时test1已经销毁(销毁理应a为undefined)

在这里插入图片描述

test1执行结束之后应该销毁掉scope chain和对应的AO,但此时test2也连着test1的AO,所以消除不掉.把test2再return给一个外部的变量test3的时候,操作test3即执行test2,能够调用已经结束的test1的AO

如上,当内部函数(test2)被返回到外部(return test2;)并保存时(var test3 = test1()😉,一定会产生闭包,闭包会产生原来的的作用域链不释放的现象(test2仍拥有test1的AO),过度的闭包可能会导致内存泄漏或加载过慢(占用内存).

function test() {
    var n = 100;
    function add() {
        n++;
        console.log(n);
    }

    function reduce() {
        n--;
        console.log(n);
    }
    // 返回两个函数可以用数组实现
    return [add, reduce];
}

var arr = test();
arr[0]();
arr[1]();


// arr[i]刚才只是保存了函数名,调用函数不加括号,执行函数加括号
GO: {
    arr: undefined,
    function test() { },    
}
AO: {
    n: undefined,
    function add() { },
    function reduce() { },
        
}

test.[[scope]] -> 0 : test.AO
                  1 : GO


add.[[scope]] -> 0 : add.AO X //后面执行的时候又会生成,且1号和2号保存的也能用
                 1 : test.AO
                 2 : GO
                 
                 
reduce.[[scope]] -> 0 : reduce.AO X //后面执行的时候又会生成,且1号和2号保存的也能用
                    1 : test.AO
                    2 : GO
                    
//101
//100

//实例
function breadManager(num) {
    var breadNum = arguments[0] || 10;

    function supply() {
        breadNum += 10;
        console.log(breadNum);
    }

    function sale() {
        breadNum--;
        console.log(breadNum);
    }

    return [supply, sale];
}
                 
var breadManager = breadManager(50);

breadManager[0]();
breadManager[1]();
// 注意,"var breadManager = breadManager(50);"中supply()和sale()仅仅被定义而未被执行!!所以这句话不会改breadNum的值

//60
//59
//除了数组,也能用对象的方式试用闭包
function sunSched(thing) {
    var sunSched = '';

    var operation = {
        setSched: function (thing) {
            sunSched = thing;
        },
        showSched: function () {
            console.log("My schedule on sunday is " + thing)
        }
    }

    return operation;
}

var sunSched = sunSched('studying');
sunSched.setSched('playing');
sunSched.showSched();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值