闭包的理解

2021-07-12

看到了一段关于闭包的新描述,主要是在词法闭包方面。这次是站在Lisp方言的角度考察。

Scheme中变量的作用域被限定在了源码中定义其的那个括号里。作用域与源代码书写方式一致的作用域称为“词法闭包(Lexical closure)”或“静态作用域(Static scope)”。采用静态作用域减轻了程序员的负担,因为它已经在代码中体现了,因此你可以很容易理解。另一方面,还有一种被称为“动态作用域(Dynamic scope)”的作用域。这种作用域仅在程序运行时确定。由于会在调试时带来种种问题,这种作用域现在已经不再使用。

参考:

2020-11-18

研究过《 Ruby 原理剖析》,至于 Python,Ruby,JavaScript 都差不多。至少模型是通用的

我简单再自问自答一下:

闭包产生的形式代码 大概是—— 函数 A 内部定义了函数 B,内部函数 B 引用了外部函数 A 的变量,A 函数返回了函数 B 。 一般来说,一个函数执行完毕,就会被回收掉。这里有点区别,函数 A 执行完毕,返回的是 B 。B 还引用者 A 的变量。

这就是闭包了。被 B 引用的变量,由于存在引用关系无法被切断。就像一个小背包一样,永远携带着。永远可以访问。 反过来,也就无法被回收内存。

本质上底层,是函数 B 保存了对外部环境也就是 A 的作用域链的引用,其实是一个指针。Python,Ruby 都是这样实现的。JS 没看过 V8 源码,应该也是一样的。

闭包有什么好处呢? 其实是有好处的 —— 可以极大地简化代码。 如果没有闭包,会如何? 访问变量,必须靠传参。闭包可以自动向外顺着保存的作用域链的指针,向外自动查找变量。无形中大量简化了代码。

JS,Ruby 中大量的使用闭包,可以让代码非常简洁清晰。 这就是闭包,一个聪明的设计,把一个频繁使用的行为,固化到解释器内部,帮你做。


我以前不同时期的思考

https://www.v2ex.com/t/245098#reply11

Mark24

Everything can Mix.