<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function createCounter() {
let count = 0;
return {
increament : function() {
count++;
},
reset: function() {
count = 0;
},
getCount: function() {
return count;
},
name: "计数器"
};
}
const counter1 = createCounter();
const counter2 = createCounter();
counter1.increament();
counter1.increament();
console.log(counter1.getCount()); // 输出 2
console.log(counter2.getCount()); // 输出 0
counter2.increament();
console.log(counter2.getCount()); // 输出 1
counter1.reset();
console.log(counter1.getCount()); // 输出 0
console.log(counter1.name);
</script>
</body>
</html>
这里创建了一个函数工厂createCounter,并且将函数作为值赋给了两个变量。这两个变量就拥有的私有的数据,互不影响。
这就是闭包。
在javascript中在语法层面支持了闭包。
在java中,想实现同样的效果的话,可以通过lambda表达式
import java.util.function.IntSupplier;
public class Counter {
public static void main(String[] args) {
IntSupplier counter = counterSupplier();
System.out.println(counter.getAsInt()); // 输出:0
System.out.println(counter.getAsInt()); // 输出:1
counter.getAsInt(); // 增加计数,但不打印
System.out.println(counter.getAsInt()); // 输出:2
}
public static IntSupplier counterSupplier() {
int[] count = new int[1]; // 使用数组来存储状态
return () -> {
count[0] += 1; // 每次调用时增加计数
return count[0]; // 返回当前计数
};
}
}
java的实现,明显比js的代码更不容易懂。你需要补充了解一下函数式接口的知识,下面是IntSupplier接口的代码,可以看到这个接口定义了一个getAsInt方法,而js中是直接在返回的对象中,定义函数名,和函数实现代码。
package java.util.function;
@FunctionalInterface
public interface IntSupplier {
/**
* Gets a result.
*
* @return a result
*/
int getAsInt();
}