martes, 18 de junio de 2013

Metodos y variables privadas en Javascript

En Javascript no existen palabras reservadas como public o private, no hay class, solo objetos que heredan de otros y todos los campos de cualquier objeto son públicos.

Pero, entonces ¿Cómo es posible usar Javascript en diversos aspectos y con una orientación a objetos?

Pues para ello existe algo llamado closure (clausura).

Si una función externa devuelve una función interna, la función interna tiene acceso a las variables de la función externa, incluso si la función externa es devuelta posteriormente. Para que esto quede claro podemos ver lo siguiente:

function funcionExterna(variable) {
    var  variableDeLaFuncionExterna = variable;
    return function funcionInterna() {
        return variableDeLaFuncionExterna;
    }
}

var foo = functionExterna(20);
foo(); // Esto devolvera 20

Si nos percatamos la funcion interna esta siendo llamada antes de que la funcion externa sea retornada y funciona. Esto es un closure.

Con un ejemplo voy a tratar de explicarlo mejor, si tuvieramos el siguiente código:

var futbolista = {
    "goles": 0,
    "anotaGol": function(gol){
        if (gol > 0) this.goles += gol;
    }
};

futbolista.anotaGol(5);
console.log(futbolista.goles); //Devuelve 5
futbolista.anotaGol(3);
console.log(futbolista.goles); //Devuelve 8

Se podría modificar a futbolista, incluso sin hacer uso de su anotaGol, eso podría ser peligroso, sobre todo en proyectos grandes donde hay muchos archivos y variables, que facilmente podrían confundir a todos.

En ese caso sería mejor algo como esto:

var jugador = function(){
    var acumuladorPrivado = 0;
    return {
        "obtenerGoles":function(){
        return acumuladorPrivado;
        },
        "anotaGol":function(gol){
            if (gol > 0) acumuladorPrivado += gol;
        }
    };
};

var sergio = new jugador();
console.log(sergio.acumuladorPrivado); //Devuelve undefined
console.log(sergio.obtenerGoles()); // Devuelve 0
sergio.anotaGol(4); // Agrega 4 al acumuladorPrivado
console.log(sergio.obtenerGoles()); // Devuelve 4

Y tenemos un singleton. :)

No hay comentarios:

Publicar un comentario