重识 JavaScript —— 闭包(三)

什么是闭包?

这确实是个问题,我现在答不出来。在这里想聊一个有趣的现象,在中学时代,常常有老先生在解答我们提出问题时,他们可以给出正确的结果。但是说不出个所以然出来,然后老先生会告诉我们:

这个东西阿,只可意会不可言传呐,你们多练习就可以自行体会其中的奥义啦。

我认为这世间的事物可意会即可言传,不可言传者只能说明水平还不够,还得修行。古有诸葛孔明在《隆中对》用寥寥数语为刘备做了一个缜密的顶层设计。

嗯,有点跑偏,没关系,我现在说不清,我们可以看看别人怎么说。

维基百科上对于闭包的定义:

在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。运行时,一旦外部的 函数被执行,一个闭包就形成了,闭包中包含了内部函数的代码,以及所需外部函数中的变量的引用。其中所引用的变量称作上值(upvalue)。

《javascript高级程序设计》(第三版)

闭包是指有权访问另一个函数作用域中的变量函数;

《javascript权威指南》 (第六版)

从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。

我最喜欢是《javascript高级程序设计》中的这个描述,因为他最短,嗯我觉得他说得最清楚。闭包就是能让我们能在函数外部访问到函数内部的成员。

还记得上一篇中最后的那个疑问吗?

在 JS 里,我们有没有方法打破常规,在外层作用域访问内层作用域的值呢?

闭包的作用

闭包是 JavaScript 最强大的功能之一

这里给一个详细描述闭包的文档 http://jibbering.com/faq/faq_notes/closures.html

我认为闭包很重要的两个功能是:

  1. 能够读取其他函数内部变量的函数
  2. 让这些变量的值始终保持在内存中。

看一段简单代码

var fn1 = function() {
    var count = 1;

    var innerFn = function(){
        return count++; 
    }
    // 这里将一个函数作为返回值
    return innerFn;
}
var fn2 = fn1();
console.log(fn2()); // 1

console.log(fn2()); // 2

console.log(fn2()); // 3

console.log(fn2()); // 4

// 上一篇写作用域中留下了一个疑问,就是我们有没有办法在外层作用域中访问内层作用域中的局部变量(属性)
// 由于在 innerFn 中是可以访问父函数 fn1 作用域内的变量的,所以我们想在 fn1 外访问 fn1 中的变量可以借助 innerFn 来完成。这也是万物皆值类型语言(JS、Lua、Swift、Go...)的一个很重要的特性——闭包
// 这里打印出来的连续的数,说明 count 常驻在内存中,并没有在 fn2 方法结束时回收掉 count
// 我对此的理解是:由于 fn2 是 fn1 的返回值,而 fn2 函数依赖 fn1 中的局部变量 count, 所以 GC 不会回收 count
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值