JavaScript: ¿Cómo se usan las variables de instancia?

¿Por qué esto no funciona como se esperaba? (ver comentario esperado)

var Module = function () {
    var public_instance_var;

    function doStuff () {
        Module.doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        public_instance_var: instance_var,
        doStuff: doStuff,
        doOtherStuff: doOtherStuff
    }
}();

Module.doStuff();

Actualizar: Se corrigió de acuerdo con algunas de las sugerencias de jAndy

preguntado el 31 de julio de 12 a las 12:07

parece que te perdiste instancia_var -

¿Hay un error tipográfico en la devolución? ¿Dónde está definido instance_var? -

Module.doStuff(); deberia arrojar el error que Module no tiene una propiedad exigible doStuff (o similar). La línea con su comentario nunca se ejecuta. Además, esto realmente no tiene nada que ver con OOP. -

3 Respuestas

Múltiples errores aquí:

  • Tu no regresas DoStuff como interfaz de módulo
  • instance_var no está declarado, probablemente significó public_instance_var
  • doOtherStuff nunca se asigna a Module, solo llámalo como doOtherStuff();

Código fijo:

var Module = function () {
    var public_instance_var;

    function doStuff() {
        doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        doStuff: doStuff,
        public_instance_var: public_instance_var
    }
}();

Module.doStuff();

Respondido 31 Jul 12, 12:07

public_instance_var: instance_var revela un puntero público a la propiedad privada public_instance_var y, por lo tanto, es correcto en mi código. El resto de tu observación parece correcta. - stevek-pro

cambia tu código así

var Module = function () {
    var public_instance_var;

    function doStuff () {
        doOtherStuff();
        console.log("var is ", public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        public_instance_var: public_instance_var,
        doStuff : doStuff
    }
}();

Module.doStuff();
  • tienes que volver doStuff() función (de lo contrario fuera será indefinido) y public_instance_var en lugar de instance_var
  • necesitas ejecutar doOtherStuff() sin anteponer Module.

Respondido 31 Jul 12, 12:07

Lo que hace este código es, simplemente: crear y ejecutar una función y asignar su valor de retorno a una variable: Module. El valor devuelto es un objeto con 1 propiedad: public_instance_var, que apunta a la variable instance_var, o (después de corregir el error tipográfico: public_instance_var). Esta variable fue declarada, pero no instanciada. Por lo tanto, el valor de retorno se ve así:

Module.public_instance_var = undefined

La última línea Module.doStuff(); no funcionará ni un poco: el módulo es un objeto que no tiene métodos. Las funciones que declaró se recolectan como basura cuando regresa la función anónima. Si desea acceder a esas funciones, deberá incluirlas en la declaración de devolución. Lea sobre los cierres, los constructores de objetos y los patrones de diseño en general, pero diría que el código que está buscando se verá así:

var Module = (function()
    var public_instance_var;
    function doStuff () {
        this.doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };
    function doOtherStuff() {
        public_instance_var = true;
    };
    return {
        public_instance_var: public_instance_var,
        doStuff: doStuff,
        doOtherStuff: doOtherStuff
    };
})();

Por supuesto, de esta manera su variable public_instance_var es una propiedad pública, por lo que supongo que lo que realmente está tratando de hacer es simular propiedades y métodos privados. En cuyo caso, podría terminar con un código similar a este:

var Module = (function()
{
    var public_instance_var;
    return {
        //public_instance_var: public_instance_var, remove this line
        //the closure will preserve access to the variable
        doStuff: function ()
        {
            this.doOtherStuff();//this, you're referencing the object's property
            console.log('here I am');
        },
        doOtherStuff: function ()
        {
            public_instance_var = true;
            //this won't work anymore:
            //this.public_instance_var = true;
        };
    }
})();

Module.doStuff() ahora registra here I am, Pero el doOtherStuff ahora también es un método público. Así es como puede elegir resolver el problema:

var Module = (function()
{
    var public_instance_var;
    function doOtherStuff ()
    {
        public_instance_var = true;
    };
    return {
        //public_instance_var: public_instance_var, remove this line
        //the closure will preserve access to the variable
        doStuff: function ()
        {
            doOtherStuff();//don't use this here, but the reference to the function exists thanks to closure
            console.log('here I am');
            console.log(public_instance_var);//logs true
        }
    };
})();

Estas son solo algunas de las cosas muy poderosas que puede hacer con cierres y funciones que devuelven objetos.
Acabo de leer un par de artículos, como este uno, hay mejores por ahí. Google el término power constructors

Respondido 31 Jul 12, 13:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.