var a= [];
for(var i = 0; i < 9; i++) {
  a.push(function() {console.log(i);});
}

a[0](); //9

var a= [];
var make_func = function(i) {return function() {console.log(i)}}
for(var i = 0; i < 9; i++) {
  a.push(make_func(i));
}

a[0](); //0

var a= [];
for(let i = 0; i < 9; i++) {
  a.push(function() {console.log(i);});
}

a[0](); //0
var a = [];
var b = {x : 999};

var make_fuc = function (i) { return function () {console.log(i.x);}}

var i = 0;
for(i = 0; i < 10; i++) {
  b.x = i
  a.push(make_fuc(b));
}

a[1]();//9

值传参对闭包的影响。

Java8在使用lambda时外部变量必须为等效final。

int sum = 0;
list.forEach(x -> sum += x.size());

如果没有等效final限制,那么外面的sum应该不会变的(值传参)。

int[] sum = new int[1];
list.forEach(x -> sum[0] += x.size());

要达成效果也是可以的。

java 8 in action

Restrictions on local variables

You may be asking yourself why local variables have these restrictions. First, there’s a key difference in how instance and local variables are implemented behind the scenes. Instance variables are stored on the heap, whereas local variables live on the stack. If a lambda could access the local variable directly and the lambda were used in a thread, then the thread using the lambda could try to access the variable after the thread that allocated the variable had deallocated it. Hence, Java implements access to a free local variable as access to a copy of it rather than access to the original variable. This makes no difference if the local variable is assigned to only once—hence the restriction. Second, this restriction also discourages typical imperative programming patterns (which, as we explain in later chapters, prevent easy parallelization) that mutate an outer variable.

Closure

You may have heard of the term closure and may be wondering whether lambdas meet the definition of a closure (not to be confused with the Clojure programming language). To put it scientifically, a closure is an instance of a function that can reference nonlocal variables of that function with no restrictions. For example, a closure could be passed as argument to another function. It could also access and modify variables defined outside its scope. Now Java 8 lambdas and anonymous classes do something similar to closures: they can be passed as argument to methods and can access variables outside their scope. But they have a restriction: they can’t modify the content of local variables of a method in which the lambda is defined. Those variables have to be implicitly final. It helps to think that lambdas close over values rather than variables. As explained previously, this restriction exists because local variables live on the stack and are implicitly confined to the thread they’re in. Allowing capture of mutable local variables opens new thread-unsafe possibilities, which are undesirable (instance variables are fine because they live on the heap, which is shared across threads).