JavaScript 闭包

闭包概念:

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。

 

什么时候才会触发闭包呢?

当两个函数互相嵌套,把里面的函数被保存到了外部(全局),里面的函数在外面执行的时候,一定能够调用里面的变量。

 

看下面这个例子:

a函数里面包含b函数,执行a的时候,返回了b函数,赋值给了外部变量demo,通过作用域及上下文的学习可理解到,因为a和b是引用关系,虽然a执行完后销毁了自己的AO,但是被b保留下来了,并将引用地址保留到了外部的变量。

上面的函数,可以用图解来说明其作用域及执行上下文关系:

a被定义和执行的状态图,如下图

b被定义的状态如下图

a执行完就释放了自己的AO,但是b还引用了a的AO,并保留到了外部(全局),如下图

闭包的作用:

  • 实现公有变量  eg:函数累加器
  • 可以做缓存(存储结构)  eg:eater
  • 可以实现封装,属性私有化。eg:Person()
  • 模块化开发,防止污染全局变量

看一个例子:

1-为什么返回的函数数组结果是 10 ?

理解核心:返回的是函数数组,数组中的每个元素都形成一个闭包(并共用同一个闭包),所以,当外部执行这个闭包时,预编译里的AO对象,它的 i 因for循环,最后值已经变为了 10。

2-这是不好的闭包例子,因为它输出了10个 10,怎么改成一个好的闭包,让它循环输出对应的0123456789;

//问题1-为什么输出 10 ?
        function test() {
            var arr = [];
            for (var i = 0; i < 10; i ++) {
                arr[i] = function () {
                    document.write(i)
                }
            }
            return arr;
        }
//问题2-这是不好的闭包例子,因为它输出了10个 10,怎么改成一个好的闭包,让它循环输出对应的0123456789;
        var myArr = test();
        for(var j = 0; j < 10; j++){
            myArr[j]();
        }
------------------------------------------------------------------------------------
//修改后
        function test() {
            var arr = [];
            for (var i = 0; i < 10; i ++) {
                //下面是一个立即执行函数,j为形参,接收循环的每一个i,独立保存到了外部
                (function (j) {
                    arr[j] = function () {
                    document.write(j)
                    }
                }(i))

            }
            return arr;
        }

        var myArr = test();
        for(var j = 0; j < 10; j++){
            myArr[j]();
        }

可以实现封装,属性私有化,如下代码

function Deng(name, wife) {
    var prepareWife = "xiaozhang";   
    this.name = name;
    this.wife = wife;
    this.devorce = function () {
        this.wife = prepareWife;
    }
    this.changePrepareWife = function (target) {
        prepareWife = target;
    }
    this.sayPreparewife = function () {
        console.log(prepareWife);
    }
}

//创建邓哥这个角色,原配老婆叫xiaoliu
//当创建出来的时候,还带了三个闭包,三对一的闭包:devorce changePrepareWife sayPreparewife 
//怎么理解呢?
//这几个闭包是外人看不见的,只有邓哥自己知道,是邓哥的私有数据

var deng = new Deng('deng', 'xiaoliu');

//直接打印deng.prepareWife 是没有这个属性的
//只有他执行了changePrepareWife (改变了预备人选)再sayPreparewife (说出来),才知道他有其它妻子人选 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1学习者1

打赏作者一杯咖啡与妹子坐坐吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值