java很难模拟闭包?还是我对闭包理解有误?

2019-03-25 13:40|来源: 网路

今天看《Javascript高级程序设计》一书,其中对闭包下了一个定义:

闭包是词法表示包括不必计算的变量的函数。(原书第56页)

还给了一个简单的样例:

var t = "hello world";

function closure(){
   alert(t);
}



因为变量t在函数closure之外定义,所以closure就是一个必包。

如果这样的话,用java模拟闭包有何难?


public class SimulateClosure{

    private int num;
    public void setNum(int num){
        this.num = num;
    }

    public void closure(int origin){
        System.out.println(origin*num);
    }

}

客户端调用:

SimulateClosure sc = new SimulateClosure();
sc.setNum(1);
sc.closure(5);// 输出5
sc.setNum(2);
sc.closure(5);// 输出10 



我写的这个例子是不是闭包?closure方法也使用了方法外部的字段。。客户端调用结果也不同。。

闭包就这么简单吗?还是我的理解有错误?请高手指教。

问题补充
达人们,你们在哪里??快来拍我
问题补充
谢谢猫姐!那我写的例子不是闭包,书中提供的例子是不是闭包呢?

相关问答

更多
  • 1. 闭包的概念 首先还得从基本概念说起,什么是闭包呢?来看下维基上的解释: 复制代码代码如下: 在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。 .... 上面提到了两个关键的地方: 自由变量 和 函数, 这两个关键稍 ...
  • 1)函数类型可以使用方法句柄吗? Scala面向没有方法句柄的JDK 5和6,所以它还没有试图解决这个问题。 2)我们可以摆脱“抛出”类型参数的显式声明吗? Scala没有检查异常。 3)禁止在旧式循环索引变量上使用@Shared。 Scala没有循环索引变量。 尽管如此,同样的想法可以用某种类型的while循环来表达。 Scala的语义在这里非常标准。 符号绑定被捕获,如果符号碰巧映射到一个可变参考单元然后在你自己的头上。 4)处理像Comparator这样的接口,它们定义了多个方法,但其中一个方法来自O ...
  • 闭包只是很棒的工具。 何时使用它们? 任何时候你都喜欢......如前所述,另一种选择是写一个班; 例如,C#2.0之前,创建一个参数化的线程是一个真正的斗争。 在C#2.0中,你甚至不需要你只需要的`ParameterizedThreadStart': string name = // blah int value = // blah new Thread((ThreadStart)delegate { DoWork(name, value);}); // or inline if short 比较一下 ...
  • 国际海事组织,即使有更多的代码行,在你的特定例子中, transform版本看起来更具可读性。 为什么? 因为这个词, 转化 。 您立即知道正在执行集合中的转换,而对于正常版本,您必须遵循代码流程以了解它的意图。 一旦你掌握了这些新的构造,你会发现它们更具可读性。 IMO, even with more lines of code, the transform version, in your particular example, looks more readable. Why? Because of ...
  • 这里已经提到:on()调用在Lua注册表中保存对回调闭包的引用。 我想这个闭包将从sock对象的__gc元方法中的Lua注册表中清除, 但是如果闭包引用了sock对象,则不会收集sock对象。 要解决这个问题,你应该避免在sendchunk()函数体中对sock upval的引用进行硬编码。 例如,利用传递给回调函数的第一个参数始终是套接字对象的事实。 function sendfile(sock, name) local fd = file.open(name, "r") local fun ...
  • 尝试这个: this.filter( hasId ).filter( function () { return inResult( result ); }).each( function () { console.log( this.id ); }); 在你的代码中你有.filter(inResult(result)) ,它不会工作,因为你立即调用inResult并将调用的结果 (这是一个布尔值)传递给filter() ,这不适用于布尔值。 你也可以这样做: var keys = Obje ...
  • 鉴于闭包是一个编译器功能而不是一个平台功能,没有什么是不能用它们完成的。 您可以编写编译器手动使用的所有代码(当涉及表达式树时,有一些例外,编译器可以访问一些未被语言公开的IL指令)。 但是,你很生气, 不要在LINQ中使用闭包,你需要访问封闭变量。 例如: public List FilterByAge(IEnumerable people, int age) { return people.Where(p => p.Age >= age).ToList(); } ...
  • 数组是对象,它们有一个push()方法。 没什么不寻常的。 callListeners()函数没有声明任何命名参数,但是JavaScript允许使用比声明的参数更多的参数来调用函数,并且完整的参数列表可用作特殊名称arguments 。 callListeners()在action.apply()调用中使用arguments来调用具有callListeners()本身的相同参数列表的action函数。 callListeners()的目的是用一些参数调用它,并用这些参数调用listeners数组中的所有函数 ...
  • 不要将变量与对象混淆:来自局部变量的引用确实被复制,但它仍然引用相同的对象,在您的情况下是映射。 有一个广为人知的习惯用于解决final限制,包括数组: final int[] x = {1}; ... use in an anonymous instance... System.out.println(x[0]); Don't confuse the variable with the object: the reference from the local variable is indeed cop ...
  • Artima对当前(2009年12月)的情况有一个很好的总结 。 一年前,Sun Microsystems的首席工程师Mark Reinhold宣布,在比利时安特卫普举行的Devoxx会议上,Java的下一个主要版本JDK 7将不包括闭包。 然而,在今年的同一次会议上,莱因霍尔德突然宣布Java将会在JDK 7中获得关闭 Artima has a good summary of the current (Dec 2009) situation. One year ago, Mark Reinhold, Pr ...