深入浅出-js闭包

闭包

在内部函数使用外部函数的变量,就会形成闭包。闭包保留了外部环境的引用
如果内部函数被返回到了外部函数的外面,在外部函数指向完成后,依然可以使用闭包里的值

闭包的形成

在内部函数使用外部函数的变量,就会形成闭包

例子1:

function a{
	var aa = 100
	function b{
	//在内部b函数里使用外部a函数的变量aa,此时就**形成了闭包**,aa:100
	//但是因为没有return回去所以**没有保持闭包**
		console.log(aa)
	}
	b()
}
a()

闭包的值存储在closure中,但因为没有return所以不会保持,b函数执行完,这里的闭包便会消失(有很多js书籍也没有很权威直接的说明这里是否形成闭包,只不过在浏览器debug运行时确实有闭包)
在这里插入图片描述
例子2:

function a{
	var aa = 100
	function b{
	//形成了闭包	{b:fun}
		console.log(b)
	}
	b()
}
a()

代码执行顺序:由上往下执行,先检查函数a,在再下面调用函数a。
1.产生a的AO对象
aAO:{aa: undefined;b:function}
2.调用函数a
3.a的AO对象变成:
aAO:{aa: 100;b:function}
4.产生b的AO对象
bAO:{}
[[scopes]] - 0:bAO ;1:aAO; 2:GO

2.闭包的保持

如果希望在调用函数后,闭包依旧保持,就需要将内部函数返回到外部函数的外部
例子1:

function a(){
	var num = 0
	function b(){
		console.log(num++)
	}
	return b
}
var demo = a() 
demo()
demo()

执行过程:
预编译:GO:{a:function;demo:undefined}
1.var demo = a()这里执行a()
产生aAO{num:0;b:function}
GO变成{a:function;demo:b(){console.log(num++)}}
2.第一个demo()
等于执行b(),产生bAO{} [[scopes]] - 0:bAO;1:aAO;2:GO
num++,num在外部a()函数,所以这里形成了闭包。
因为num++是先打印原来的值再++;所以这里打印的值是0,num的值是1
3.第二个demo()
等于执行b(),产生新的bAO{} [[scopes]] - 0:bAO;1:aAO;2:GO
num++,num在aAO作用域里num = 1,打印原来的值1;num的值是2

	这就是闭包的保持

闭包的条件

1.闭包要形成:在内部函数使用外部函数的变量
2.闭包要保持:内部函数返回到外部函数的外面

闭包的应用

1.一般情况下,函数外部是访问不到函数内部的变量的,所以需要通过闭包来操作函数里的变量
2.实现封装
3.防止全局变量的污染
例子:

function a(){
            var name 
            function Setname(name) {
                this.name = name
            }
            function Getname() {
                return this.name
            }
            return {
                Setname:Setname,
                Getname:Getname
            }
        }

        var b = a()
        console.log(b);
        b.Setname('xiaoe');
        console.log(b.Getname());

运行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值