¿Puedo "extender" una "clase" de cierre en Javascript?
inheritance closures (3)
Ese patrón de "clase" no es un patrón de "clase", se conoce como patrón de módulo . Devuelve un objeto que no tiene vínculos con la función que lo creó aparte de la disponibilidad de sus variables privadas. El objeto devuelto NO es una instancia de la función que lo creó.
Cuando llamas ''nueva clase ()'' crea una instancia de esa función, pero también devuelve otro objeto. Cualquier otra operación es en realidad en el objeto devuelto y no en la instancia.
Para usar la herencia, realmente necesitas usar la herencia prototípica correctamente, te sugiero que leas:
- Herencia prototípica por Douglas Crockford
- Miembros privados en JavaScript por Douglas Crockford
- Prototipos y herencia en JavaScript por Scott Allen (nota: proto no es estándar)
Otras lecturas:
Lamento dejarte con material de lectura, pero me parece que estás explorando posibilidades. Estos artículos le darán una visión más profunda sobre el asunto.
Una vez que sepa más sobre el tema, lo más probable es que ignore los miembros privados por completo y use el prefijo _ y lo convierta en un miembro público como todos los demás;) Es más fácil y los miembros privados son inútiles de todos modos.
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" de Welcomer
de manera que pueda 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();
La respuesta simple a tu pregunta es No.
No puede hacer nada para obtener acceso a esas var
cosas definidas, a menos que su función esté en el mismo ámbito, o de alguna manera "haga pública" la información (devolviéndola o configurándola).
Sin embargo, si tiene acceso para editar la función original, puede reescribir las cosas de tal manera que esas funciones puedan "pasar" a una función de extensión, lo 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();
Si realmente necesitas herencia, hay algunas bibliotecas que te ayudarán enormemente. Una opción es trait.js , que puede convertirse en una parte estándar de javascript en algún punto de todos modos. Si eso no hace flotar su barco, las bibliotecas como jQuery y el prototipo tienen ayudantes para la herencia.
Si desea ir con un enfoque mínimo / desde cero, le sugiero que utilice el modelo de prototipo para todo. Verá un gran aumento de rendimiento sobre el patrón que tiene en sus ejemplos.
Para responder más directamente a su pregunta, no. Tendrá un tiempo más fácil si diseña sus "clases" para que no se confíe en las funciones privadas.