闭包理解
JS里
js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包
function a()
{
var i=0;
return function (){return ++i;}
};
var c=a(); // 得到函数b
c(); //执行函数b,得到1
Go里
ype Counter func() int func newCounter(last int) Counter { return func() int { res := last last++ return res } } counter1 := newCounter(1) counter2 := newCounter(2) fmt.Println(counter1(), counter1(), counter2(), counter2()) // 1 2 2 3
通过闭包与面向对象的对比理解闭包
闭包(Closure)也称为函数闭包,它是一个可访问本函数体外变量的函数,相当于扩大了该函数的作用域。使用闭包的目的是将状态和对状态的操作封装在一起,它是函数式编程里对该目的的实现,例如JS、Go等函数为一等公民的语言里常有上述闭包示例的用法;在面向对象编程里则用类来实现该目的,即在类内定义状态变量及对该变量的操作函数。
可见,函数式编程里的闭包和面向对象里的对象都可用来解决“状态和对状态操作的封装”的问题,若不借助这俩,则一种思路是定义全局变量然后函数去操作该变量,显然不优雅。
闭包和对象的相同点和不同点:
相同点:都包含状态和操作。对象与闭包并无根本的区别。它们都是对状态的管理,只是使用的方法不同。
不同点:对于对象,从外部看,状态和操作都不见了,看到的是一个新的物体,称为对象;而对于闭包,从外部看,它就是一个头等函数,状态被隐藏到了操作中,即为函数绑定了作用域。对象看着是对象,闭包看着像函数。
很多语言两者都支持,如JS、Go、Java。闭包早于面向对象出现,没有绝对的孰优孰劣,只是不同语言的设计原则导致支持的程度不同。
闭包与lambda
lambda表达式可理解为匿名函数。闭包与lambda没必然的联系,即闭包的定义和生成不一定需要lambda表达式、lambda表达式的使用也不一定产生闭包。
参考资料:
https://lotabout.me/2015/Closure-%E5%86%85%E6%B6%B5%E7%90%86%E8%A7%A3/
https://lotabout.me/2016/thoughts-of-closure/