本人开始接触编程是从js开始的,当时网上很多人说闭包是难点,各种地方对闭包的解释也是千奇百怪。如今开始接触js以外的各种编程语言,发现不光是js,php、java、c++等各种编程语言里都有闭包,而且大体意思是差不多的。
js里的闭包
比较权威的高程里是这样解释闭包的:
闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另
一个函数。
当初看这个解释有点懵逼,理解成闭包就是函数中的函数了。现在看来感觉有点问题,不知道是不是翻译的问题,全局作用域下的函数不也是闭包吗?
再看下mdn的解释:
Closures (闭包)是使用被作用域封闭的变量,函数,闭包等执行的一个函数的作用域。通常我们用和其相应的函数来指代这些作用域。(可以访问独立数据的函数)
这是啥, 一脸懵逼。
个人理解:闭包就是一个函数,它引用了外部变量,有这两个条件就形成了闭包
在我们日常使用中,外部变量很少是全局变量,经常是用一个母函数return一个子函数,子函数引用母函数中的变量。这个病了因为被引用了,所以母函数执行完它并没有被销毁,成为了自由变量。
php里的闭包
最近不满足于只干前端的活,开始用起了php。php不愧是最好的语言,抄起来就是一梭子。php里也有闭包,下面对比着js来看一下。
php官网对闭包的解释:
匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。
php里的闭包和js其实很像啊,也是和函数有关,其实也是能访问自由变量的函数,常用在回调函数。值得一题的是php的闭包闭的更彻底,他不能主动访问外部变量,而是要主动用use关键词传进去,而且这个传参还是值传递,如果想引用传递还得加上&。
$example = function () {
var_dump($message);
};
$example = function () use (&$message) {
var_dump($message);
};
各位觉得php这个设定是多此一举吗?个人觉得这样更保险啊。
Golang里的闭包
最近在学习go语言,让我们来看一下go语言里的闭包。
go的官方教程里如此写道:
Function closures
Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.
For example, the adder function returns a closure. Each closure is bound to its own sum variable.
例子:
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
翻译一下:
函数闭包
go中函数可以形成闭包,闭包是返回的函数在函数体外仍引用了其中的变量。作为值返回的函数可以访问和修改引用的变量,在这种情况下,返回的函数和函数体中的变量相互关联。
例子中,adder函数返回一个闭包,每个闭包就与同一个sun变量有关联。
在go中,闭包特指将函数作为值返回的情况,被返回的函数引用了生成它的母函数中的变量。
学习了go里的闭包我感觉自己前面的理解似乎有些问题,所以做了一些修改。
评论里一位大神总结的非常好:
从内存回收角度考虑更容易理解闭包,正常函数调用完后内部的变量就会销毁,但闭包却能使本该销毁的变量一直保留。
reference:
不装逼地解释闭包-方应杭
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。