基本概念
数学意义
闭包有什么作用
闭包通常出现在将函数当作第一级对象的语言中——在这些语言中,函数可以被当作参数传递,也可以作为返回值返回,就像字符串、整数等简单类型。例如以下Scheme代码:
; Return a list of all books with at least THRESHOLD copies sold. (define (best-selling-books threshold) (filter (lambda (book) (>= (book-sales book) threshold)) book-list))
在这个例子中,lambda表达式(lambda (book) (>= (book-sales book) threshold))
出现在函数best-selling-books
中。当这个lambda表达式被执行时,Scheme创造了一个包含此表达式以及对threshold
变量的引用的闭包,其中threshold
变量在lambda表达式中是自由变量。
这个闭包接着被传递到filter
函数。这个函数的功能是重复调用这个闭包以判断哪些书需要增加到列表那些需要丢弃。因为闭包中引用了变量threshold
,所以它在每次被filter
调用时都可以使用这个变量,虽然filter
可能定义在另一个文件中。
下面是用ECMAScript (JavaScript)写的同一个例子:
// Return a list of all books with at least 'threshold' copies sold. function bestSellingBooks(threshold) { return bookList.filter( function (book) { return book.sales >= threshold; } ); }
这里,关键字function
取代了lambda
,Array.filter
方法[5]取代了filter
函数,但两段代码的功能是一样的。
一个函数可以创建一个闭包并返回它,就像这样:
// Return a function that approximates the derivative of f // using an interval of dx, which should be appropriately small. function derivative(f, dx) { return function (x) { return (f(x + dx) - f(x)) / dx; }; }
因为在这个例子中闭包已经超出了创建它的函数的范围,所以变量f
和dx
将在函数derivative
返回后继续存在。在没有闭包的语言中,变量的生命周期只限于创建它的环境。但在有闭包的语言中,只要有一个闭包引用了这个变量,它就会一直存在。清理不被任何函数引用的变量的工作通常由垃圾回收完成。