Pregunta

Tengo una "clase" de JavaScript definida así:

var Welcomer = function(name) {
  var pName = name;
  var pMessage = function() {
    return "Hi, " + pName + "!";
  };

  return {
    sayHi: function() {
      alert(pMessage());
    }
  };
};

new Welcomer('Sue').sayHi();

¿Hay alguna forma de "subclase"? Welcomer ¿De tal manera que puedo redefinir los métodos públicos y tener acceso a los métodos y variables privados? Lo siguiente me dará acceso a los métodos públicos, pero no a los privados:

var UnhappyWelcomer = function(name) {
  var pSadMessage = function() {
    // won't work, b/c I don't have access to pMessage
    return pMessage() + " Miserable day, innit?";
  };

  return {
    sayHi: function() {
      alert(pSadMessage());
    }
  };
};
UnhappyWelcomer.prototype = Welcomer(); // failed attempt at inheritance

new UnhappyWelcomer().sayHi();
¿Fue útil?

Solución

La respuesta simple a su pregunta es No.

No puedes hacer nada para acceder a esos var cosas definidas, a menos que su función esté en el mismo alcance, o de alguna manera "hacer pública" la información (devolviéndola o configurandola en this).

Sin embargo, si tiene acceso para editar la función original, podría reescribir las cosas de tal manera que esas funciones podrían "pasar" a una función extendida, que puede alterar el alcance "protegido" del objeto. El siguiente código debe dar una buena idea de lo que estoy proponiendo.

var Welcomer = function(name) {
  var _protected = {
    name: name,
    message: function() {
      return "Hi, " + _protected.name + "!";
    }
  };

  return {
    extendWith: function(extender) {
      extender.call(this, _protected);
      return this;
    },
    sayHi: function() {
      alert(_protected.message());
    }
  };
};

var UnhappyWelcomer = function(name) {
  var self = Welcomer(name).extendWith(function(_protected) {
    _protected.sadMessage = function() {
       return _protected.message() + " Miserable day, innit?";
    };
    // extending the public while still having scope to _protected...
    this.sayHi = function() {
      alert(_protected.sadMessage());
    };
  });
  return self;
};

UnhappyWelcomer('bob').sayHi();

Otros consejos

Ese patrón de "clase" no es un patrón de "clase", se conoce como un Patrón de módulo. Devuelve un objeto que no tiene vínculos con la función que la creó otra que la disponibilidad de sus variables privadas. El objeto devuelto no es una instancia de la función que la creó.

Cuando llama a 'New Class ()', crea una instancia de esa función, pero también devuelve otro objeto. Cualquier operación adicional está realmente en el objeto devuelto y no en la instancia.

Para usar la herencia, realmente necesita usar la herencia prototípica correctamente, le sugiero que lea:

Otras lecturas:

Lamento dejarte material de lectura, pero me parece que estás explorando las posibilidades. Estos artículos darán una visión más profunda sobre el asunto.

Una vez que sepa más sobre el asunto, lo más probable es que ignore a los miembros privados y use el prefijo _ y simplemente hágalo un miembro público como todos los demás;) Es más fácil y los miembros privados no tienen sentido de todos modos.

Si realmente necesita herencia, hay algunas bibliotecas que ayudarán enormemente. Una opción es rasgo.js, que en realidad puede convertirse en una parte estándar de JavaScript en algún momento de todos modos. Si eso no flota en su barco, bibliotecas como jQuery y prototipo tienen ayudantes para la herencia.

Si desea ir con un enfoque mínimo/desde el racha, le sugiero que use el modelo prototipo para todo. Verá un gran aumento de rendimiento sobre el patrón que tiene en sus ejemplos.

Para abordar más directamente su pregunta, no. Tendrá un momento más fácil si diseña sus 'clases' para que no se confien las funciones privadas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top