类(java)和闭包(javascript)之间的区别?

我不明白封闭比类更强大。 看起来我可以使用类实现相同的闭包行为。 任何帮助,将不胜感激

关闭是穷人的对象/对象是穷人的关闭

请参阅: 闭包和物体

对于懒惰:

尊敬的大师Qc Na和他的学生Anton一起走路。 希望提醒大师进行讨论,安东说:“师父,我听说物体是件好事 – 这是真的吗?” Qc Na怜悯地看着他的学生并回答说:“愚蠢的学生 – 对象只是一个穷人的封闭。”

被严厉批评,安东从他的主人那里离开并回到他的牢房,打算研究关闭。 他仔细阅读了整个“Lambda:The Ultimate …”系列论文及其表兄弟,并实现了一个带有基于闭包的对象系统的小型Scheme解释器。 他学到了很多,并期待通知他的主人他的进步。

在他与Qc Na的下一次行走中,安东试图通过说“师父,我已经努力研究这件事,并且现在明白物体真的是一个穷人的封闭物”来打动他的主人。 Qc Na用他的棍子打了安东,说:“你什么时候学习?闭锁是穷人的目标。” 那一刻,安东开悟了。

– Anton van Straaten

closureclass是两个截然不同的东西。

说“一个closure更强大”是不正确的。 或者相反。

他们完全不同的事情。

closure在基本意义上是一个函数调用,它保留了创建它的作用域的局部变量信息。

class是对象的定义。 该类定义了行的实例和内容。

其他人已经解释了类和闭包之间的差异。 我只是想指出,在Java API的许多地方,支持它们的语言将/可以使用闭包,使用接口的匿名实现。 例如,考虑以下代码:

 JButton btn = new JButton("Say Hello"); btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageBox("Hello"); } }); 

在这种情况下,可以说匿名ActionListener充当闭包,如果Java允许闭包,代码可能如下所示:(使用c ++ 0x-esque语法)

 JButton btn = new JButton("Say Hello"); btn.addActionListener([]=>(ActionEvent e){JOption.showMessageBox("Hello");}); 

在这个简单的案例中,闭包和接口(AII)的匿名实现之间的主要区别在于:

  1. AII方法比闭包具有更强的类型检查。 (关闭系统可以做更强的类型检查,但一般来说,它们不是)
  2. 闭包语法需要更少的输入。 一旦你足够长时间地咀嚼Java需要的闭包参数,这似乎是一个主要的抱怨。

我还没遇到AII无法做需要做的事情。 是的,有更多的输入和另一个界面来定义,但他们的系统工作,恕我直言,更强大,因为你不需要使用AII,而是可以使用一个完整的类与它自己的方法,成员数据和构造函数。 一个示例是弹出上下文菜单的动作侦听器。 如果你创建一个实现ActionListener的类并将JMenu作为它的参数,你可以这样做:

 btn.addActionListener( new ContextMenuActionListener(myMenu) ); 

这比使用boost:bind类型解决方案看起来更清晰(对我来说)。

 []=>(ActionListener) myContextPopupClosure = []=>(ActionListener E){ ... }; ... btn.addActionListener( Closure.bind1(myContextPopupClosure,myMenu) ); 

或者

编辑:

昨晚做了大量工作后搞乱了generics,我意识到关闭AII的一个优势。 在上面的例子中,我一直假设闭包的类型为[] =>(ActionEvent),但它确实可以是[] =>(?super ActionEvent)类型。 意即:

 []=>(Object) c = []=>(Object o) { System.exit(0); } btn.addActionClosure( c ); window.addMouseMovedClosure( c ); //Each method in MouseMotion listener would need it's own closure. //So I 'invented' an API change. 

可以编译。 这可能是有用的,因为当你需要做同样的事情来响应多个事件。

另一个例子。 这种封闭可以添加到任何关闭的地方。 如果作为ActionListener或MouseListener添加到某个东西,它将记录调用。

 []=>(Object ... objs) log = []=>(Object ... obj) {for(Object o:obj){logObject(o);}} 

我不确定是什么导致了你这个问题,但是你被告知或者你读过的东西严重误导了你。

完全忽略语言, 闭包和类是编程中完全不相关的结构/约定。

这是一个很好的问题,但措辞可能更好:

“Java对象和JavaScript闭包之间有什么相似之处和区别”?

相似之处:它们在局部变量中都具有持久状态。 他们的方法可以访问那些状态变量。

差异:Javascript是一种函数式语言,因此可以立即调用和返回函数内的函数。 例如:

 newXY = function(x,y) { var that = {};//Instantiate new object var x = parseFloat(x); var y = parseFloat(y); that.xtimesy = function() { return x*y; }(); // <-- Notice the immediate invocation of the function, here. return that; }; 

所以你可以编写这样的代码片段,从rhino shell复制/粘贴:

 js> var foo = newXY(2,5); js> foo.xtimesy; 10