Closure 003

by Jelgab

HTML

<h3>
Closure 003
</h3>

<div id = "Resultados" >
  &nbsp;
</div>

<hr/>
<a href = "javaScript:void(0)" onclick = "agregarBotones01A()">agregar Botones 01A</a>
<a href = "javaScript:void(0)" onclick = "agregarBotones01B()">agregar Botones 01B</a>
<a href = "javaScript:void(0)" onclick = "agregarBotones01C()">agregar Botones 01C</a>
<br/>
<a href = "javaScript:void(0)" onclick = "agregarBotones02A()">agregar Botones 02A</a>
<a href = "javaScript:void(0)" onclick = "agregarBotones02B()">agregar Botones 02B</a>
<a href = "javaScript:void(0)" onclick = "agregarBotones02C()">agregar Botones 02C</a>

JavaScript

//Closure 003
console.clear();

function printResults( theValue ){
   $("#Resultados").append( theValue );
   $("#Resultados").append( $("<br/>") );
}

/*
- Hacer referencia a la variable i del ciclo, causa el problema "Closure on a variable modified in loop of outer scope"
- agregarBotones01 muestra el problema
- i no se pierde al salir del ciclo for. Su valor queda en 5 (El # que no cumplió e hizo que se acabara el ciclo)
- Cuando se ejecuta el evento es cuando se mira el valor de i. En ese momento ya vale 5
 */

//El que falla:
function agregarBotones01A() {
  $(document.body).append( $("<hr/>") );
  //document.body.appendChild( document.createElement( "hr" ) );

  for (var i = 0; i < 5; i++) {
    var elBoton = document.createElement("button");

    elBoton.appendChild( document.createTextNode( "Button A" + i ) );
    elBoton.addEventListener( "click", function() { printResults( i ); } );
    document.body.appendChild( elBoton );
  } /*for (var i = 0; i < 5; i++)*/
} /*function agregarBotones01A()*/

//No sirve:
var globalUno = 0;
function agregarBotones01B() {
  $(document.body).append( $("<hr/>") );
  //document.body.appendChild( document.createElement( "hr" ) );
    
  for (var i = 0; i < 5; i++) {
    var elBoton = document.createElement("button");

		globalUno = i;
    
    elBoton.appendChild( document.createTextNode( "Button B" + i ) );
    elBoton.addEventListener( "click", function() { printResults( globalUno ); } );
    document.body.appendChild( elBoton );
  } /*for (var i = 0; i < 5; i++)*/
} /*function agregarBotones01B()*/

//No sirve:
function agregarBotones01C() {
  $(document.body).append( $("<hr/>") );
  //document.body.appendChild( document.createElement( "hr" ) );
    
  for (var i = 0; i < 5; i++) {
    var elBoton = document.createElement("button");

		var localC = i + 0;
    
    elBoton.appendChild( document.createTextNode( "Button C" + i ) );
    elBoton.addEventListener( "click", function() { printResults( localC ); } );
   ...