你不知道的闭包

前言

这篇文章不是全面讲闭包知识的,而是针对那些已经对闭包有所了解但是还存在疑惑的人群。比如:闭包为何能保存变量?接下来就详细讲述此类问题。以下内容来自犀牛书第六版。

正文

经典闭包案例

函数柯里化:

function curry(fn){
    var arg1 = Array.prototype.slice.call(arguments,1);
    return function(){
        var arg2 = Array.prototype.slice.call(arguments);
        var mergeArr = arg1.concat(arg2);
        return fn.apply(null,mergeArr);
    }
}

function add(num1,num2){ 
    return num1 + num2;
}

var curriedAdd = curry(add, 5); 
alert(curriedAdd(3)); // 8

疑惑

外部函数中定义的局部变量在函数返回之后就不存在了,那么嵌套的函数是如何调用不存在的作用域链的呢?如上面所示,调用curriedAdd()的时候,第一次传入的5是存在的。那么5为什么能保存在函数变量里面的呢?

实现闭包

闭包:函数定义时的作用域链到函数执行时仍然有效。

我们将函数作用域描述为一个对象列表,不是绑定的栈。每次调用javascript函数的时候,都会为之创建一个新的局部变量对象来保存局部变量,把这个对象添加至作用域链中。当函数返回的时候,就从作用域链中将这个绑定变量的对象删除。

1.如果不存在嵌套的函数,也没有其他引用指向这个绑定的对象,它就会被当做垃圾回收掉。
2.如果定义了嵌套的函数,每个嵌套的函数都各自对应一个作用域链,并且这个作用域链指向一个变量绑定对象。
(1)如果这些嵌套函数对象在外部函数中保存了下来(比如赋值给外部函数中的某个变量),它们也会和所指向的变量绑定对象一样当做垃圾回收
(2)但是如果这个函数定义了嵌套函数,并将它们作为返回值返回,或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套函数,它就不会被当做垃圾回收。并且它所指向的变量绑定对象也不会被当作垃圾回收。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值