Foros del Web » Programando para Internet » Javascript »

Clausura (clousure) y/o Encapsulación

Estas en el tema de Clausura (clousure) y/o Encapsulación en el foro de Javascript en Foros del Web. Saludos corillo, Estoy preparando un material (tutorial) y en ese material requiero encapsular ciertos valores. Para los que no conocen el termino de closure o ...
  #1 (permalink)  
Antiguo 03/04/2011, 09:40
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Clausura (clousure) y/o Encapsulación

Saludos corillo,

Estoy preparando un material (tutorial) y en ese material requiero encapsular ciertos valores. Para los que no conocen el termino de closure o encapsulating, pueden leer estos materialesAhora me surge una duda de la forma como ustedes encapsularían. Si hago esto
Código HTML:
Ver original
  1. *{ cursor: default; }
  2. div{
  3.     background-color: #eee;
  4.     margin-top: 2px;
  5.     text-align: center;
  6.     font-size: 20px;
  7. }
  8. div:hover{ background-color: #ccc; }
  9. </head>
  10. <div id="foo">foo</div>
  11. <div id="bar">bar</div>
  12. <div id="baz">baz</div>
  13. <div id="candy">candy</div>
  14. <div id="fruits">fruits</div>
  15. <div id="vegetable">vegetable</div>
  16.  
  17. <script type="text/javascript">
  18. var divs = ['foo', 'bar', 'baz', 'candy', 'fruits', 'vegetable'];
  19. for(var i in divs){
  20.     var elem = document.getElementById(divs[i])
  21.     if (elem.addEventListener){
  22.         elem.addEventListener('click', function(e){
  23.             alert(divs[i])
  24.         }, false);
  25.     }else if (elem.attachEvent){
  26.         elem.attachEvent("onclick", function(e){
  27.             alert(divs[i])
  28.         });
  29.     }
  30. }
  31. </body>
  32. </html>
Siempre me traerá el último valor, ya que de por sí estoy haciendo referencia a la variable directamente y no al valor, por eso me trae siempre el último valor. Pero si lo hiciera así
Código HTML:
Ver original
  1. *{ cursor: default; }
  2. div{
  3.     background-color: #eee;
  4.     margin-top: 2px;
  5.     text-align: center;
  6.     font-size: 20px;
  7. }
  8. div:hover{ background-color: #ccc; }
  9. </head>
  10. <div id="foo">foo</div>
  11. <div id="bar">bar</div>
  12. <div id="baz">baz</div>
  13. <div id="candy">candy</div>
  14. <div id="fruits">fruits</div>
  15. <div id="vegetable">vegetable</div>
  16.  
  17. <script type="text/javascript">
  18. var divs = ['foo', 'bar', 'baz', 'candy', 'fruits', 'vegetable'];
  19. for(var i in divs){
  20.     (function(eDiv){
  21.         var elem = document.getElementById(eDiv)
  22.         if (elem.addEventListener){
  23.             elem.addEventListener('click', function(e){
  24.                 alert(eDiv)
  25.             }, false);
  26.         }else if (elem.attachEvent){
  27.             elem.attachEvent("onclick", function(e){
  28.                 alert(eDiv)
  29.             });
  30.         }
  31.     })(divs[i])
  32. }
  33. </body>
  34. </html>
Se resuelve el problema porque estoy haciendo referencia al valor no a la variable persé. Mi pregunta es ¿qué forma ustedes recomendarían usar?
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Última edición por abimaelrc; 03/04/2011 a las 09:52 Razón: Modificar código para cross-browsing
  #2 (permalink)  
Antiguo 03/04/2011, 10:26
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 19 años, 11 meses
Puntos: 834
Respuesta: Clausura (clousure) y/o Encapsulación

Está bien así, aunque lo mejor sería crear una función addEvent y usar forEach (https://developer.mozilla.org/en/Jav.../array/foreach)
  #3 (permalink)  
Antiguo 03/04/2011, 10:33
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Respuesta: Clausura (clousure) y/o Encapsulación

Gracias Panino

Bueno, más bien lo traje, por el tutorial que estoy preparando de GMaps y de esta forma de encapsular fue que pude lograrlo, ya que ellos preparon lo de los eventos y quería más bien saber otra forma de lograrlo, si es que hay una forma de hacerlo así de anonima como la que estoy mencionando.

Aunque me diste una idea a ver si me sale
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #4 (permalink)  
Antiguo 03/04/2011, 11:15
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 19 años, 11 meses
Puntos: 834
Respuesta: Clausura (clousure) y/o Encapsulación

Algo así te decía:
Código PHP:
<html>
<
head>
<
style>
*{ 
cursor: default; }
div{
background-color#eee;
margin-top2px;
text-aligncenter;
font-size20px;
}
div:hoverbackground-color#ccc; }
</style>
</
head>
<
body>
</
style>
<
div id="foo">foo</div>
<
div id="bar">bar</div>
<
div id="baz">baz</div>
<
div id="candy">candy</div>
<
div id="fruits">fruits</div>
<
div id="vegetable">vegetable</div>
<
script type="text/javascript">
if (!Array.
prototype.forEach)
{
  Array.
prototype.forEach = function(fun /*, thisp */)
  {
    
"use strict";

    if (
this === void 0 || this === null)
      throw new 
TypeError();

    var 
Object(this);
    var 
len t.length >>> 0;
    if (
typeof fun !== "function")
      throw new 
TypeError();

    var 
thisp arguments[1];
    for (var 
0leni++)
    {
      if (
i in t)
        
fun.call(thispt[i], it);
    }
  };
}
function 
addEvent(obj,fun,type){ 
    if(
obj.addEventListener){ 
        
obj.addEventListener(type,fun,false); 
    }else if(
obj.attachEvent){ 
        var 
f=function(){ 
            
fun.call(obj,window.event); 
        } 
        
obj.attachEvent('on'+type,f); 
        
obj[fun.toString()+type]=f
    }else{ 
        
obj['on'+type]=fun
    } 
}  
var 
divs = ['foo''bar''baz''candy''fruits''vegetable'];

divs.forEach(function(div,i,o){addEvent(document.getElementById(div),function(e){alert(this.id);},'click');});
</script>
</body>
</html> 

Última edición por Panino5001; 03/04/2011 a las 11:23
  #5 (permalink)  
Antiguo 03/04/2011, 11:53
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Respuesta: Clausura (clousure) y/o Encapsulación

Gracias, lo voy a tener en cuenta
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #6 (permalink)  
Antiguo 03/04/2011, 12:10
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: Clausura (clousure) y/o Encapsulación

buenas gentes!

antes quise contestar este tema y me faltaba poco pero por deberes que tenia que cumplir no me fue posible publicar el mensaje. de todos modos, lo que queria compartir era que en teoria el codigo esta bien. en javascript, para crear un closure se necesita de un scope. dichos scopes solamente se pueden crear con funciones. de modo que la forma en que lo has hecho es correcta.

ahora bien, viendo el codigo de panino, me parece el mas adecuado. porque desde el evento, la informacion la obtiene desde el elemento.

__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #7 (permalink)  
Antiguo 03/04/2011, 12:24
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Respuesta: Clausura (clousure) y/o Encapsulación

Gracias zero.

Gmaps no lo trabaja de esa forma, sino que tienes que declararlo. Para que me entiendas mejor, te posteo un ejemplo sencillo de Gmaps
Código HTML:
Ver original
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  4.     <title>test</title>
  5.     <style>
  6.     *{ margin: 0; padding: 0; }
  7.     html, body, #map{
  8.         width: 100%;
  9.         height: 100%;
  10.     }
  11.     </style>
  12.     <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script>
  13.     <script type="text/javascript">
  14.     window.onload = function(){
  15.         var options = {
  16.             zoom: 9
  17.             , center: new google.maps.LatLng(18.2, -66.4)
  18.             , mapTypeId: google.maps.MapTypeId.ROADMAP
  19.         };
  20.  
  21.         var map = new google.maps.Map(document.getElementById('map'), options);
  22.  
  23.         var place = new Array();
  24.         place['San Juan'] = new google.maps.LatLng(18.465, -66.105);
  25.         place['Mayagüez'] = new google.maps.LatLng(18.215, -67.14);
  26.         place['Ponce'] = new google.maps.LatLng(18.025, -66.615);
  27.         place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);
  28.         place['Culebras'] = new google.maps.LatLng(18.315, -65.3);
  29.         place['Vieques'] = new google.maps.LatLng(18.125, -65.44);
  30.  
  31.         for(var i in place){
  32.             var marker = new google.maps.Marker({
  33.                 position: place[i]
  34.                 , map: map
  35.                 , title: i
  36.             });
  37.  
  38.             google.maps.event.addListener(marker, 'click', function(){
  39.                 var popup = new google.maps.InfoWindow();
  40.                 popup.setContent('Lugar: ' + i);
  41.                 popup.open(map, marker);
  42.             })
  43.         }
  44.     };
  45.     </script>
  46. </head>
  47.     <div id="map"></div>
  48. </body>
  49. </html>
De esta forma tiene un problema es que se muestra siempre el último seleccionado. Como todavía no me he puesto a observar con detenimiento el código de Panino, no sé como implementarlo, pero la forma más sencilla que vi como lograr que eso funcione correctamente es así
Código HTML:
Ver original
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  4.     <title>test</title>
  5.     <style>
  6.     *{ margin: 0; padding: 0; }
  7.     html, body, #map{
  8.         width: 100%;
  9.         height: 100%;
  10.     }
  11.     </style>
  12.     <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script>
  13.     <script type="text/javascript">
  14.     window.onload = function(){
  15.         var options = {
  16.             zoom: 9
  17.             , center: new google.maps.LatLng(18.2, -66.4)
  18.             , mapTypeId: google.maps.MapTypeId.ROADMAP
  19.         };
  20.  
  21.         var map = new google.maps.Map(document.getElementById('map'), options);
  22.  
  23.         var place = new Array();
  24.         place['San Juan'] = new google.maps.LatLng(18.465, -66.105);
  25.         place['Mayagüez'] = new google.maps.LatLng(18.215, -67.14);
  26.         place['Ponce'] = new google.maps.LatLng(18.025, -66.615);
  27.         place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);
  28.         place['Culebras'] = new google.maps.LatLng(18.315, -65.3);
  29.         place['Vieques'] = new google.maps.LatLng(18.125, -65.44);
  30.  
  31.         for(var i in place){
  32.             var marker = new google.maps.Marker({
  33.                 position: place[i]
  34.                 , map: map
  35.                 , title: i
  36.             });
  37.  
  38.             (function(i, marker){
  39.                 google.maps.event.addListener(marker, 'click', function(){
  40.                     var popup = new google.maps.InfoWindow();
  41.                     popup.setContent('Lugar: ' + i);
  42.                     popup.open(map, marker);
  43.                 })
  44.             })(i, marker);
  45.         }
  46.     };
  47.     </script>
  48. </head>
  49.     <div id="map"></div>
  50. </body>
  51. </html>
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #8 (permalink)  
Antiguo 03/04/2011, 13:43
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: Clausura (clousure) y/o Encapsulación

¿se puede saber donde me dejastes Humacao?

comprendo la situacion... como toda libreria, el API tiene tendencias a cambiar la forma en que escribimos. de todos modos, sin usar closure, esto fue lo que hice y me funciono perfectamente. en referencia al primer codigo, por supuesto.
Código javascirpt:
Ver original
  1. popup.setContent('Lugar: ' + this.title);
  2. popup.open(map, this);
la explicacion es bien sencilla. fijate que this en el evento hace referencia al objeto marker pasado como argumento en la invocacion de addListener, ya que es al objeto a quien se le esta aplicando el evento.

pd: lo de Humacao son bromas.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.

Última edición por zerokilled; 03/04/2011 a las 13:51
  #9 (permalink)  
Antiguo 03/04/2011, 14:11
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 11 meses
Puntos: 1517
Respuesta: Clausura (clousure) y/o Encapsulación

Mal rayo parte es verdad se me olvida que existe this, bueno en ciertas ocaciones se me olvida

Lo digo porque en otros lados lo menciono y se me olvidó que lo puedo aplicar al objeto que se está creando en ese momento

Aquí está todo y con HUMACAO
Código HTML:
Ver original
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3.     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  4.     <title>test</title>
  5.     <style>
  6.     *{ margin: 0; padding: 0; }
  7.     html, body, #map{
  8.         width: 100%;
  9.         height: 100%;
  10.     }
  11.     </style>
  12.     <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&amp;language=es"></script>
  13.     <script type="text/javascript">
  14.     window.onload = function(){
  15.         var options = {
  16.             zoom: 9
  17.             , center: new google.maps.LatLng(18.2, -66.4)
  18.             , mapTypeId: google.maps.MapTypeId.ROADMAP
  19.         };
  20.  
  21.         var map = new google.maps.Map(document.getElementById('map'), options);
  22.  
  23.         var place = new Array();
  24.         place['San Juan'] = new google.maps.LatLng(18.465, -66.105);
  25.         place['Mayagüez'] = new google.maps.LatLng(18.215, -67.14);
  26.         place['Ponce'] = new google.maps.LatLng(18.025, -66.615);
  27.         place['Fajardo'] = new google.maps.LatLng(18.336, -65.65);
  28.         place['Culebras'] = new google.maps.LatLng(18.315, -65.3);
  29.         place['Vieques'] = new google.maps.LatLng(18.125, -65.44);
  30.         place['Humacao'] = new google.maps.LatLng(18.14, -65.88);
  31.  
  32.         for(var i in place){
  33.             var marker = new google.maps.Marker({
  34.                 position: place[i]
  35.                 , map: map
  36.                 , title: i
  37.             });
  38.  
  39.             google.maps.event.addListener(marker, 'click', function(){
  40.                 var popup = new google.maps.InfoWindow();
  41.                 popup.setContent('Lugar: ' + this.title);
  42.                 popup.open(map, this);
  43.             })
  44.         }
  45.     };
  46.     </script>
  47. </head>
  48.     <div id="map"></div>
  49. </body>
  50. </html>
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Última edición por abimaelrc; 03/04/2011 a las 14:21

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:54.