为什么一个程序中变量只能定义一次_什么是闭包?为什么叫闭包?

83c294171e095701515269f83d228d3e.png

《JavaScript ES6 函数式编程入门经典》4.1理解闭包:

简言之,闭包是一个内部函数。那么什么是内部函数呢?它是在另一个函数内部的函数。比如:

function outer() {function inner() {// body...}}

这就是闭包,函数inner称为闭包函数。闭包函数如此强大的原因在于它对作用域链的访问。


fd90de84e0933d82fd8ba5370cb9b577.png

《JavaScript高级程序设计(第3版) [Professional JavaScript for Web Developers 3rd Edition] 》

7.2 闭包

有不少开发人员总是搞不清匿名函数和闭包这两个概念,因此经常混用。闭包是指有权访问另一个函数作用域的函数。创建闭包的常见方式,就是在一个函数内,创建另一个函数。


7e31123187de958bbdadf204215849cc.png

《代码之髓 编程语言核心概念》

代码这髓 第11章 对象与类 11.5

什么是闭包

说到闭包( closure)这个概念,想必很多人一时也说不出究竟何为闭包。它是创建具有对象性质的事物的一种技术。

很多语言都支持定义带有某种状态的函数。比如,可以定义像计数器一样每调用一次显示的数字加1的函数。我们用 JavaScript语言来实现一下。

function makeCounter(){var count = 0function push(){count++;console. log(count);} return push; }c = makeCounter()c()  // -> 1c()  // -> 2c()  // -> 3

这段代码中,函数 makeCounter中定义了变量 count和函数push,并返回函数push。然后,通过调用函数 makeCounter将返回值赋给变量c,然后调用它三次。每调用一次,显示的值就加1.这是怎么做到的呢?函数 make Counter首先创建了一张名字和值的对照表,把变量 count的值设为0.然后定义了函数push,并将其返回。函数push将其被定义时的对照表一同带出 makeCounter函数。随后,每当被调用时,函数push在被定义时的对照表的值就加1。

事实上,并没有所谓闭包的特殊的语法结构。如果有一种语言,它可以在函数中定义函数,有允许嵌套的静态作用域,并且可以把函数作为返回值传递给变量,那么它只要通过函数的嵌套就可以实现带有某种状态的函数

为什么叫做闭包

看到闭包这个名字,总有一种什么东西被严实地包裹起来了的感觉。为什么会叫做闭包呢?某 Standard ML的教材上做了如下解释。

为什么把这称为闭包?一个包含了自由变量的开放表达式,它和该自由变量的约束环境组合在一起后,实现了一种封闭的状态。

—- Ake Wikstrom, Functional programming using standard ML, Prentice-Hall, 1987.

拿上面一段代码来讲,函数push使用了变量 count,然而该变量并不是在函数push中定义的。这种变量被称为自由变量。函数push就是一个包含了自由变量的开放函数。而函数 makeCounter的对照表中为0的值和为 count的名字结合在了一起。这种给值绑定一个名字的操作叫做(名字)约束。

这样开放函数push和 makeCounter的对照表组合配套之后,无需在这以外的作用域中寻找变量的定义,从而达到了某种完备的状态。通过这样表现出一种封闭的属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值