闭包

最近在琢磨闭包到底是什么,终于在MDN上找到了答案

概念

闭包是函数和声明该函数的词法环境的组合

词法作用域

  • 词法作用域的函数中遇到内部无法解析的局部变量时,去函数定义时的环境中查询。
  • 在 C 和 PHP 中,函数内变量的值只能来自 内部定义传参使用全局变量 ,也就是说所有函数都只有一个全局的 词法环境
  • 然而在 JS 中由于函数内可以就近原则的访问到外部函数的变量,因此每一个函数都有它的 词法环境

闭包

JS 中一个函数和它的词法环境是绑定在一起的,无论这个函数被传递到哪,在哪执行,其函数内的变量引用都是固定的。即使函数引用了一个局部变量,而且这个局部变量所在的函数已经执行完毕,这个变量也是驻留在内存中的。

用途

  • 在面向对象编程中,对象的方法可以与对象的属性或者其他方法相关联,而闭包则通过词法环境与其所要操作的数据相关联
  • 闭包显而易见的用途是增强了函数的功能,函数可以与不同的词法环境组成闭包,用更少量的代码解决问题
  • 在函数是一等公民的语言中,函数通过变量进行传递,闭包将会更加强大

其他语言的闭包

在一些面向对象的语言 Java 和 PHP 中, 方法能访问到的外部变量是来自于自身实例的。一个方法要绑定不同的外部变量,可以通过新建不同的实例来解决。然而新建实例和赋值操作有点繁琐,就新增了 匿名内部类匿名函数 等方法来解决。PHP 更是直接把 PHP 中的闭包函数与匿名函数等同起来(闭包函数际上是Closure类,一个特殊的内置类),而 Java8 也新增了 Lambda 表达式(本质上是匿名内部类)。这些语法糖掩盖不了闭包在这些语言中功能受限的事实

参考