2010-04-24 15 views
12

¿Hay alguna manera de llamar a las funciones javascript "públicas" desde las "privadas" dentro de una clase?Accediendo a métodos "públicos" desde métodos "privados" en la clase javascript

Mira la clase a continuación:

function Class() 
{ 
    this.publicMethod = function() 
    { 
     alert("hello"); 
    } 

    privateMethod = function() 
    { 
     publicMethod(); 
    } 

    this.test = function() 
    { 
     privateMethod(); 
    } 
} 

Aquí está el código corro:

var class = new Class(); 
class.test(); 

Firebug da este error:

publicMethod no está definido: [pausa de esta error] publicMethod();

¿Hay alguna otra manera de llamar a publicMethod() dentro de privateMethod() sin acceder a la variable de clase global [es decir class.publicMethod()]?

+4

Espero que sea solo un error tipográfico en su ejemplo aquí, pero su 'privateMethod' es una variable global. –

+0

En Firefox si invoco 'class.privateMethod()' hay un error, mientras que 'class.publicMethod()' funciona bien, por lo que parece que hay alguna diferencia entre las dos funciones. – mon4goos

Respuesta

5

La respuesta aceptada tiene el efecto secundario indeseable, posiblemente, que se crearán copias separadas de publicMethod, test y privateMethod en cada caso. El idioma para evitar esto es:

function Class() 
{} 

Class.prototype=(function() 
{ 
    var privateMethod = function(self) 
    { 
     self.publicMethod(); 
    } 


    return 
    { 
     publicMethod: function() 
     { 
      alert("hello"); 
     }, 
     test: function() 
     { 
      privateMethod(this); 
     } 
    }; 
}()); 

En otras palabras, es necesario pasar el this a la función privada como argumento. A cambio, obtiene un prototipo verdadero sin tener que contaminar cada instancia con sus propias versiones de las funciones públicas y privadas.

+2

¡Agradable! En lugar de pasar, siempre puedes 'privateMethod.call (this)' también – gnarf

8

Puede guardar una variable en el ámbito del constructor para mantener una referencia al this.

Nota: En su ejemplo, que quedan fuera var antes privateMethod = function() haciendo que privateMethod global. He actualizado la solución aquí:

function Class() 
{ 
    // store this for later. 
    var self = this; 
    this.publicMethod = function() 
    { 
    alert("hello"); 
    } 

    var privateMethod = function() 
    { 
    // call the method on the version we saved in the constructor 
    self.publicMethod(); 
    } 

    this.test = function() 
    { 
    privateMethod(); 
    } 
} 
2

La respuesta de torazaburo es la mejor, ya que evita la creación de copias múltiples de los miembros privados. Me sorprende que Crockford no lo mencione en absoluto. Alternativamente, dependiendo de la sintaxis que prefiera para declarar funciones miembro públicas, se puede hacer esto:

function Class() 
{} 

(function() { 
    var privateMethod = function(self) { 
     self.publicMethod(); 
    }; 

    Class.prototype.publicMethod = function() { 
     alert('hello'); 
    }; 

    Class.prototype.test = function() { 
     privateMethod(this); 
    }; 
}()); 
0

¿No es este enfoque uno aconsejable? No estoy seguro aunque

var klass = function(){ 
    var privateMethod = function(){ 
    this.publicMethod1(); 
    }.bind(this); 

    this.publicMethod1 = function(){ 
    console.log("public method called through private method"); 
    } 

    this.publicMethod2 = function(){ 
    privateMethod(); 
    } 
} 

var klassObj = new klass(); 
klassObj.publicMethod2(); 
Cuestiones relacionadas