简体   繁体   English

Java lambdas是否等同于JavaScript闭包?

[英]Is a Java lambdas equivalent to a JavaScript closures?

I started learning about functional programming and I'm a bit confusing about it. 我开始学习函数式编程,我对它有点困惑。

My question is: is Java lambdas equivalent to JavaScript closures? 我的问题是: Java lambdas是否相当于JavaScript闭包? If not, what is the difference between them? 如果没有,它们之间有什么区别?

No, they are not equivalent. 不,他们不等同。 One has to do with syntax and the other with memory. 一个与语法有关,另一个与内存有关。

Lambdas are a short-hand syntax for declaring anonymous code structures. Lambdas是用于声明匿名代码结构的简写语法。

Closures are when a nested function (named or not) holds a reference to a variable from a function in an outer scope. 闭包是指嵌套函数(已命名或未命名)保存对外部作用域中函数的变量的引用。 That, in and of itself isn't really an issue. 这本身并不是一个问题。 But, when the nested function persists longer than the outer scoped variable, the variable won't be garbage collected when the outer scope terminates. 但是,当嵌套函数持续的时间长于外部作用域变量时,当外部作用域终止时,该变量不会被垃圾收集。 That's when closures become either very powerful or very annoying. 这就是闭包变得非常强大或非常烦人的时候。 It all depends on if you are intentionally using them or not. 这一切都取决于你是否故意使用它们。 Closures can allow for shared access to private data. 闭包可以允许对私有数据的共享访问。

They are "slightly different" and also "roughly equivalent". 它们“略有不同”,也“大致相当”。

tldr; tldr; a Java lambda that access an outer-scoped variable 1 is also a closure; 访问外部范围变量1的Java lambda 也是一个闭包; and a JavaScript "closure" that does not access an outer-scope variable is not strictly a closure (and can be more precisely called an anonymous function 2 ). 并且不访问外部作用域变量的JavaScript“闭包” 不是严格意义上的闭包(可以更准确地称为匿名函数2 )。


In JavaScript, a closure generally implies "being able to re-assign variables in the outer scope" - however, having access to or "closing over / binding" a variable is sufficient for an anonymous function to be a closure 3 . 在JavaScript中,闭包通常意味着“能够在外部作用域中重新分配变量” - 但是,有权访问或“关闭/绑定”变量足以使匿名函数成为闭包3

Java lambda's requires that all variables from the outer scope accessed in a lambda are effectively final which means they cannot be re-assigned. Java lambda要求在lambda中访问的外部作用域中的所有变量都是有效的 ,这意味着它们不能被重新赋值。

1 The rule is that a [Java] lambda expression can only access local variables from an enclosing scope that are effectively final. 1规则是[Java] lambda表达式只能访问有效最终的封闭范围内的局部变量。 An effectively final variable is never modified—it either is or could be declared as final - http://www.informit.com/articles/article.aspx?p=2303960 一个有效的最终变量永远不会被修改 - 无论是或者可以被宣布为最终变量 - http://www.informit.com/articles/article.aspx?p=2303960

However, since a Java lambda can capture a read-only variable binding to mutable objects, it is possible for a Java lambda to indirectly modify state in the outer context and can thus emulate the ability to "re-assign" values. 但是,由于Java lambda 可以捕获绑定到可变对象的只读变量,因此Java lambda可以间接修改外部上下文中的状态,从而可以模拟“重新分配”值的能力。

2 In computer science, a closure is a function that has an environment of its own. 2在计算机科学中,闭包是一种具有自己环境的函数。 Inside this environment, there is at least one bound variable [and] anonymous functions are sometimes wrongly called closures . 在这个环境中, 至少有一个绑定变量[和]匿名函数有时被错误地称为闭包 This is probably because most languages [eg. 这可能是因为大多数语言[例如。 JavaScript] that have anonymous functions also have closures and it's common for programmers to learn about both at the same time. 具有匿名函数的JavaScript也有闭包,程序员通常同时了解它们。 - https://simple.wikipedia.org/wiki/Closure_(computer_science) - https://simple.wikipedia.org/wiki/Closure_(computer_science)

Java also has different semantics on this inside a lambda vs a JS anon-function / closure; Java也有不同的语义this拉姆达Vs的JS匿名函数/闭包内; also see JavaScript "arrow functions" which have different rules than traditional anonymous functions on how this behaves. 还看到JavaScript的“箭头功能” ,其具有比传统如何匿名函数不同的规则this行为。


3 Trivial argument: 3琐碎的论点:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM