Mar*_*ten 5 javascript java java-8
我必须将Java 8代码转换为JavaScript(单向,一生一次).为了加快速度,我希望尽可能自动化,然后使用测试套件来修复所有剩余的问题.
我想知道Java 8 lambdas和JavaScript(函数)之间的区别是什么?
任何重要的不兼容性?
比较Java lambdas和JS函数时要注意的一个重要事项是两者如何处理范围.
在Java中,lambdas只能有效地访问最终变量,并且只捕获那些明确需要的变量.在JS中,函数可以访问所有父闭包中的所有变量,从而捕获所有内容.
这样做的结果是内存泄漏的可能性,除非你知道你在做什么.举个例子:
IntSupplier getSupplier(MyMemoryHeavyClass heavy) {
int x = heavy.hashCode();
return () -> x;
}
Run Code Online (Sandbox Code Playgroud)
此方法将返回一个实际上只包含int的lambda.这里没问题.但是,JavaScript的天真翻译......
function getSupplier(heavy) {
var x = heavy.hashCode();
return function() { return x; };
}
Run Code Online (Sandbox Code Playgroud)
它一目了然可能并不明显,但这有一个重大问题.函数表达式将捕获范围内的所有内容,包括heavy参数(即使它未在返回的函数中引用).结果,它防止heavy(在该示例中需要大量内存)被垃圾收集并且因此只要返回的函数存在就将保留在存储器中.
编辑
正如评论中指出的那样,这些信息可能有点过时,因为现代引擎看起来更加智能.例如,V8显然只能捕获它认为必要的任何东西.但是,它仍然可以被欺骗,因为在同一范围内创建的所有函数似乎共享相同的闭包.
例如,添加该行(function y() { return heavy; });(否则几乎不会执行任何操作)将强制heavy进入与return x;函数使用相同的闭包中,从而创建泄漏.
虽然在这个具体的例子中牵强附会,但是当天真地翻译包含多个lambda的Java方法时,可能会发生类似的问题,这是不可想象的.