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

时间:2009-04-27 22:35:25

标签: java javascript closures

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

5 个答案:

答案 0 :(得分:11)

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

请参阅:closures and objects

懒惰:

  

尊敬的大师Qc Na   安东和他的学生一起散步。   希望能提醒大师进入   讨论,安东说:“主人,我有   听说物体非常好   事情 - 这是真的吗?“Qc Na看着   怜悯他的学生并回答说,   “愚蠢的瞳孔 - 物体只是一个   穷人的关闭。“

     被指责,安东离开了   他的主人回到他的牢房,   意图研究闭包。他   仔细阅读整个“Lambda:The   终极......“一系列论文及其论文   堂兄弟,并实施了一个小   计划翻译与   基于闭包的对象系统。他   学到了很多,并期待着   告诉他的主人他的进步。

     

在他与Qc Na,Anton的下次散步时   试图给他的主人留下深刻的印象   说“师父,我很努力   研究过这件事,现在明白了   那些物品真的是一个穷人   关闭。“Qc Na击中了回应   安东用他的棍子说:“什么时候   你会学习吗?关闭是一个穷人   男人的对象。“那一刻,安东   开悟了。

     

- Anton van Straaten

答案 1 :(得分:4)

closureclass是两回事。

说“A classclosure更强大”是不正确的。或反过来。

他们完全不同。

closure基本上是一个函数调用,它保留了创建它的范围内的局部变量信息。

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

答案 2 :(得分:4)

已经有其他人解释了类和闭包之间的差异。我只是想指出,在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需要闭包论证就会产生的主要抱怨。
  3. 我还没遇到AII无法做到需要做的事情。是的,有更多的输入和另一个界面来定义,但他们的系统工作,恕我直言,更强大,因为你不需要使用AII,而是可以使用一个完整的类与它自己的方法,成员数据和构造函数。一个示例是弹出上下文菜单的动作侦听器。如果你创建一个实现ActionListener的类并将JMenu作为它的参数,你可以这样做:

    btn.addActionListener( new ContextMenuActionListener(myMenu) );
    

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

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

    左右

    编辑:

    昨晚做了大量工作后搞乱了仿制药,我意识到封闭优于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);}}
    

答案 3 :(得分:2)

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

完全忽略语言,closureclass在编程中是完全不相关的结构/约定。

答案 4 :(得分:1)

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

“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