Java 8 Lambda构造和JavaScript之间的确切区别是什么? [英] What are the exact difference between Java 8 Lambda constructs and JavaScript?

查看:122
本文介绍了Java 8 Lambda构造和JavaScript之间的确切区别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to convert Java 8 code to JavaScript (one way, once in a lifetime). To speed things up I want to automate as much as possible and use the test suite afterwards to fix all remaining issues.

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

I wonder what the difference between Java 8 lambdas and JavaScript (functions) are?

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

Any important incompatibilities?

推荐答案

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

One important thing to note when comparing Java lambdas and JS functions is how the two treat scoping.

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

In Java, lambdas can only access effectively final variables and only captures those that are explicitly required. In JS, functions can access all variables in all the parent closures and thus captures everything.

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

A result of this is the possibility of memory leaks unless you know what you're doing. As an example:

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

此方法将返回一个仅包含int的lambda.没问题但是,天真的翻译成JavaScript ...

This method will return a lambda that effectively only contains an int. No problems here. However, a naive translation to JavaScript...

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

乍一看可能并不明显,但这是一个主要问题.函数表达式将捕获范围内的所有内容,包括heavy参数(即使未从返回的函数中对其进行引用).结果,它防止heavy(在此示例中需要大量内存)被垃圾回收,因此只要返回的函数存在,它就将保留在内存中.

It may not be obvious at a glance, but this has a major problem. The function expression will capture EVERYTHING within the scope, including the heavy parameter (even though it's not referenced from within the returned function). As a result, it prevents heavy (which in this example requires a large amount of memory) from being garbage collected and will thus remain in memory for as long as the returned function exists.

编辑

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

As pointed out in the comments, this information may be a bit out of date as modern engines appear to be more intelligent. V8, for instance, will apparently only capture whatever it deems necessary. However, it can still be tricked as all functions created in the same scope appear to share the same closure.

例如,添加行(function y() { return heavy; });否则将无济于事,将迫使heavy进入与return x;函数使用的闭合相同的闭合,从而造成泄漏.

For instance, adding the line (function y() { return heavy; });, which would otherwise do pretty much nothing, will force heavy into the same closure as the return x; function uses, creating the leak.

尽管在此特定示例中牵强,但天真地转换包含多个lambda的Java方法时,可能会发生类似的问题.

While far-fetched in this specific example, it's far from unthinkable that similar problems may occur when naively translating Java methods containing multiple lambdas.

这篇关于Java 8 Lambda构造和JavaScript之间的确切区别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆