javascript - Java 8 Lambda 构造和 JavaScript 之间的确切区别是什么?

标签 javascript java java-8

我必须将 Java 8 代码转换为 JavaScript(一种方法,一生一次)。为了加快速度,我希望尽可能实现自动化,然后使用测试套件来解决所有剩余的问题。

我想知道 Java 8 lambda 和 JavaScript(函数)之间有什么区别?

有什么重要的不兼容性吗?

最佳答案

比较 Java lambda 和 JS 函数时需要注意的一件重要事情是两者如何处理作用域。

在 Java 中,lambda 只能有效访问最终变量,并且只能捕获显式需要的变量。在 JS 中,函数可以访问所有父闭包中的所有变量,从而捕获所有内容。

这样做的结果是可能会发生内存泄漏,除非您知道自己在做什么。举个例子:

IntSupplier getSupplier(MyMemoryHeavyClass heavy) {
    int x = heavy.hashCode();
    return () -> x;
}

此方法将返回一个实际上仅包含 int 的 lambda。这里没有问题。然而,对 JavaScript 的简单翻译...

function getSupplier(heavy) {
    var x = heavy.hashCode();
    return function() { return x; };
}

乍一看可能不太明显,但这有一个很大的问题。函数表达式将捕获范围内的所有内容,包括 heavy 参数(即使它不是从返回的函数中引用的)。因此,它可以防止 heavy(在本例中需要大量内存)被垃圾回收,因此只要返回的函数存在,它就会保留在内存中。

编辑

正如评论中所指出的,由于现代引擎似乎更加智能,因此此信息可能有点过时。例如,V8 显然只会捕获它认为必要的内容。但是,它仍然可能被欺骗,因为在同一范围内创建的所有函数似乎共享相同的闭包。

例如,添加行 (function y() { return Heavy; }); ,否则几乎不会执行任何操作,将强制 heavy 进入相同的状态return x; 函数使用闭包,造成泄漏。

虽然这个具体示例有些牵强,但当天真地翻译包含多个 lambda 的 Java 方法时,可能会出现类似的问题,这绝非不可想象。

关于javascript - Java 8 Lambda 构造和 JavaScript 之间的确切区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59057560/

相关文章:

java - 通过 GMail 使用 SMTP 时如何修复 javax.mail.MessagingException?

Java 8 流 - 将方法传递给过滤器

java - 当类实现相同的接口(interface)时,Lambda 表达式会失败并出现 LambdaConversionException?

javascript - 在所有有没有 GuildID (Discord.js v12) 的机器人的服务器中使用斜杠命令

javascript - 如何重定向到 Shiny 的动态URL?

javascript - 奇怪的数据表排序和按键行为

java - 单例创建新窗口

java - 命名实体图子子图

java - 如何使用java 8更新匹配条件的列表对象

javascript - 如何使用扩展程序将代码注入(inject) facebook/google 网页?