简明的区分一下闭包和普通函数

原创
2017/01/04 09:55
阅读数 471

我不是科班出身,所以不会用专业的术语来描述。

我们都知道,一个函数(闭包或者普通函数),它可能使用三种来源的变量:

1)函数的参数; 2)函数内部定义的变量; 3)函数引用的外部变量;

这其中,<函数的参数>和<内部定义的变量>每次调用都是全新的,如果一个函数它只使用了这两类变量,那么它必然是普通的函数,或者说可以视为普通的函数(哪怕以闭包的方法来定义)。它的行为是确定的,只和调用时的参数有关,而和其他任何信息都无关。

函数还可以使用外部的变量,此时函数的行为就和外部环境脱不了关系了,比如说一个函数可能会根据文件系统的差异而选择不同的底层实现。但是这并不表示,使用了外部变量的函数就是闭包!

这里面还关系到一个变量所有权的问题!

只有一个函数使用了外部的变量,而它持有的外部变量中,至少一个只被它本身所持有,外部无法直接访问的时候,这个函数才能称为闭包!

因为外部变量不会因为函数的每次调用而被修改,函数的行为就可以更加的复杂多变。

原生闭包,一般都是通过“返回函数的函数”来实现的。以函数为参数的函数被称为高阶函数,那么以函数为返回值的函数,在python里叫做装饰器,我们也可叫它闭包工厂函数。

反过来说,即使编程语言不支持原生闭包,但是我们也可以根据闭包的定义来实现类似的功能!

比如说,用类的实例来模拟闭包。

当然,我们也可以直接硬编码一个使用外部变量的函数,然后将该外部变量隐藏起来(用namespace等),这个函数的行为和闭包也没啥差异。但是闭包工厂函数有个好处,就是:

闭包工厂函数生产的闭包,引用了闭包工厂函数每次调用时生成的内部变量,这个闭包工厂函数的内部变量(同时也是闭包的外部变量)会被闭包“劫持”,不会因闭包工厂函数的调用结束而释放(事实上也可能是产生一个被闭包劫持的拷贝),这就实现了“闭包工厂函数每次调用产生的闭包都是全新的彼此独立的”这么一个结果。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部