how garage colloctor in for-loop turn closure fishy and foxy
The most common canonical example used to illustrate closure involves the humble for-loop.
var funcs = [];
for (var i = 0; i < 3; i++) {
funcs[i] = function()
{ console.log("My value: " + i); }; }
for (var j = 0; j < 3; j++) { funcs[j](); }
Before deducing the answer,please check hidden feature in for-loop. Put an instance:
for (var i = 0; i < 2; i++) {
;
}
console.log(i);
output:<2
Notes:for-loop processes down below:
The first blockscope:var i=0;(empty function);
The second blockscope:var i=1;(empty function);
The last declaration:var i=2.
If replacing var with let,the output would be undefined.
In the canonical example,garbage collector is used.
In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector attempts to reclaim memory which was allocated by the program, but is no longer referenced—also called garbage.
Below comparisions to digest its definition:
function uniqueInteger(){
return function() { var counter = 0;return ++counter };
}
var uniqueInt = uniqueInteger();
console.log(uniqueInt());
console.log(uniqueInt());
console.log(counter)
Error: counter is not defined
function uniqueInteger(){
return function() { var counter = 0;return counter++ };
}
var uniqueInt = uniqueInteger();
console.log(uniqueInt());
console.log(uniqueInt());
output:> 0 > 0
function uniqueInteger(){
var counter = 0;
return function() { return ++counter };
}
var uniqueInt = uniqueInteger();
console.log(uniqueInt());
console.log(uniqueInt());
output:> 1 > 2
function constfuncs(){
let funcs=[];
for(var i=0;i<10;i++){
funcs[i]=()=>i;
}
return funcs;
}
console.log(constfuncs())
console.log(constfuncs()[2])
//> Array [()=>i, ()=>i, ()=>i, ()=>i, ()=>i, ()=>i, ()=>i, ()=>i, ()=>i, ()=>i]
//> ()=>i
At last,the canonical example is easy to understand.
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++)
{ // and store them in funcs
funcs[i] = function() { // each should log its value.
console.log("My value: " + i); }; }
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j](); }
Re-translate the two for loop part:
the first loop:
the first blockscope:var i=0;funcs[0]=function(){"My value:"+i};
the second blockscope:var i=1;funcs[1]=function(){"My value:"+i};
the third blockscope:var i=2;funcs[2]=function(){"My value:"+i};
the forth declaration:var i=3;
the second loop:
The first blockscope:var j=0;funs[0]()=My value: 3
The second blockscope:var j=1;funs[0]()=My value: 3
The third blockscope:var j=2;funs[0]()=My value: 3
var funcs = [];
function createfunc(i) {
return function()
{ console.log("My value: " + i); }; }
for (var i = 0; i < 3; i++) {
funcs[i] = createfunc(i); }
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j](); }
Re-translate the two for loop part:
the first loop:
The first blockscope:var i=0;funcs[0]=createfunc(0)=function(){console.log("My value: " + 0)}
The second blockscope:var i=1;funcs[1]=createfunc(1)=function(){console.log("My value: " + 1)}
The second blockscope:var i=2;funcs[2]=createfunc(2)=function(){console.log("My value: " + 2)}
the forth declaration:var i=3;
the second loop:
The first blockscope:var j=0;funs[0]()=My value: 0
The second blockscope:var j=1;funs[0]()=My value: 1
The third blockscope:var j=2;funs[0]()=My value: 2
The forth declaration:var j=3;
A new toy
Async function in loop will a little differenct,I will not explain how it works verbosely and you could copy the code and search some gist of async,it would be not inert to a bespoke tutorial for others.Propounded method before could be your daemons to sidestep thorns.
const wait = (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms));
for (var i = 0; i < 3; i++) {
// Log `i` as soon as each promise resolves.
wait(i * 100).then(() => console.log(i));
}
Note:The code is not about garbage collector,it is about Promise and loop,I mean wait will execute all loop and then then loops.
Comments
Post a Comment