当我第一次尝试理解闭包时,我遇到了一张难以理解的无法理解的计算机科学论文,我必须先了解它才能触及闭合。然后我了解到,在更多的猴子看到,猴子做基础,虽然JavaScript关键字不允许Java的成语,(原谅我的朦胧记忆在这里):
JAVA:
class ObjectWithPrivateMember()
{
private int counter;
public void ObjectWithPrivateMember()
{
counter = 0;
}
public void increment()
{
counter += 1;
}
public void decrement()
{
counter -= 1;
}
public void get_count()
{
return counter;
}
}
JavaScript(几年前的ECMAScript)没有真正的“私有”/“受保护”关键字,但Java习语的免费翻译可能是这样的:
JAVASCRIPT:
var object_with_private_member = function()
{
var counter = 0;
return {
increment: function()
{
counter += 1;
},
decrement: function()
{
counter -= 1;
},
get_count: function()
{
return counter;
}
};
}();
除了我的直接反应“Ewwwww,试图将JavaScript装扮成不可思议的东西”之外,我曾在心理上提出过这样的说法,“好吧,这就是如何用JavaScript的晦涩细节来扼杀Java成语。这可能很难直接了解JavaScript的优点。“
现在我回来解决问题“什么是真正有用的闭包?”,the Wikipedia entry提供了一些细节,并建议信息隐藏可能是主要用例,不只是在具有重度功能性弯曲的多范式语言中,而是通常对一流功能语言的怀疑。当然它更详细并且提供了更多的细微差别,但它表明教科书“具有私有字段的JavaScript对象”用例并不像我想象的那样切线。
一个优秀的函数式程序员会看到纯函数式语言或具有功能性弯曲的多范式语言的闭包的实际用例是什么?它们主要用于信息隐藏(the Wikipedia article提供比上面的漫画更多的细微差别和细节,但至少乍一看我的想法是关闭可能在JavaScript中有一个更大,更有趣的角色而不是后门的创建方式私人会员。
除了纯/多范式函数式语言中的信息隐藏机制之外,还有其他主要用例吗?
答案 0 :(得分:1)
根据我的经验,隐私事物是一个次要的考虑因素,特别是对于不可变的价值观。如果他们不能改变它,你为什么关心谁看到它?
要理解闭包的价值,首先必须理解第一类函数的值,然后很容易看出将某些数据与该函数关联起来可能很方便。
考虑尝试从维基百科页面编写以下示例而不使用闭包,但仍然使用filter
高阶函数:
// Return a list of all books with at least 'threshold' copies sold.
function bestSellingBooks(threshold) {
return bookList.filter(
function (book) { return book.sales >= threshold; }
);
}
您需要找到将threshold
传递给谓词函数的其他方法。在OOP中,您将创建某种对象,如:
class ThresholdFilter implements Filterable {
private threshold;
ThresholdFilter(threshold) {
this.threshold = threshold;
}
bool filter(book) {
return book.sales >= this.threshold;
}
}
function bestSellingBooks(threshold) {
return bookList.filter(new ThresholdFilter(threshold));
}
或者,您可以更改filter
函数以接受某种私有通用数据结构来存储和传递,这使得filter
和谓词函数更复杂,更加耦合。关闭现在开始看起来很好,我是对的吗?
还有很多情况下,闭包大大减少了耦合并简化了使用高阶函数的代码。这是函数式程序更加简洁的一个主要原因。