programacion - programación orientada a objetos de javascript
mejor enfoque a las variables miembro en javascript orientado a objetos? (5)
Este es un seguimiento de una pregunta que acabo de publicar. Me pregunto cómo manejarán todas las variables miembro en clases de JavaScript cuando usen MyClass.prototype para definir métodos.
Si define todos los métodos en la función de constructor:
function MyClass(){
this.myMethod = function(){}
}
Puede declarar muy bien las variables miembro y acceder a ellas desde dentro de sus métodos:
function MyClass(){
var myVar = "hello";
this.myMethod = function(){
alert(myVar);
}
}
Al usar la técnica Object.prototype, pierdes esta elegancia y tienes que hacerlo así;
function MyClass(){}
MyClass.prototype.myVar = "hello";
MyClass.prototype.myMethod = function(){alert(this.hello)};
No estoy loco por tener que escribir "esto" cada vez que accedo a una variable miembro. Quiero utilizar el enfoque Object.prototype por motivos de memoria y flexibilidad, pero parece mucho más complejo en cuanto a la sintaxis. ¿Es así como tu gente generalmente trabaja?
Gracias,
-Morgan
Debe usar el prototipo para almacenar métodos, porque cuando se encuentra con 100 métodos, no se copian entre instancias, sino que usan el mismo prototipo. Yo uso algo en esta línea:
var myClass = function(){};
myClass.prototype = {
method1: function(){}
,method2: function(){}
};
Debería superar su aversión a usar this
puntero para acceder a las variables de miembros.
Asigna variables miembro en el constructor, y puedes acceder a ellas con métodos prototipo:
function Cat(){
this.legs = 4;
this.temperament = ''Apathetic'';
this.sound = ''Meow'';
}
Cat.prototype.speak = function(){alert(this.sound)}
var cat = new Cat();
cat.speak();
Sí, esos atributos de objetos son públicos, pero, como diría Guido, aquí todos somos adultos. Después de todo, Javascript es un lenguaje de texto sin formato, interpretado libremente. Los beneficios de las variables "privadas" en este entorno son, en el mejor de los casos, inestables.
Digo que sea explícito y obvio acerca de cómo se debe acceder a su objeto, y los infractores se desviarán de eso bajo su propio riesgo.
La visibilidad de los atributos del objeto varía de acuerdo a cómo los declaras
function Cat( name ) {
//private variable unique to each instance of Cat
var privateName = ''Cat_''+Math.floor( Math.random() * 100 );
//public variable unique to each instance of Cat
this.givenName = name;
//this method has access to private variables
this.sayPrivateName = function() {
alert( privateName );
}
}
//this variable is shared by all cats
Cat.prototype.generalName = ''tiddles'';
//this method is shared by all cats and has no access to private vars
Cat.prototype.sayname = function( type ) {
alert( this[type+''Name''] || ''private!'' );
}
var vic = new Cat(''Victor'');
var ellers = new Cat(''Elmore'');
vic.sayname(''general''); //tiddles
vic.sayname(''given''); //Victor
vic.sayname(''private''); //private - no access
vic.sayPrivateName(); //cat will say its name
ellers.sayname(''general''); //tiddles
ellers.sayname(''given''); //Elmore
ellers.sayname(''private''); //private - no access
ellers.sayPrivateName(); //cat will say its name
Una pequeña observación (no tan) sobre las variables ''privadas'' cuando se asignan métodos al prototipo:
Es cierto que no puede usar el constructor para crear un cierre sobre sus variables, pero puede rodear los métodos prototípicos con una función anónima y obtener variables privadas compartidas entre las instancias del objeto:
function Foo() {}
(function() {
var sharedPrivateVar;
Foo.prototype.methodWithAccessToSharedPrivateVar = function() {};
})();
Con algunos giros adicionales, puede implementar sus propios mecanismos de protección, por ejemplo, variables que solo se pueden leer, no escritas a través de:
function Foo() {
this.registerInstance({ bar : ''baz'' });
this.registerInstance = undefined;
}
(function() {
var store = {}, guid = 0;
Foo.prototype.registerInstance = function(protectedProperties) {
this.__guid = ++guid;
store[this.__guid] = protectedProperties;
};
Foo.prototype.getProtectedProperty = function(name) {
return store[this.__guid][name];
};
})();
Este enfoque no sufrirá de la creación extensiva de objeto de función y cierre, pero aumenta el tiempo de búsqueda en una pequeña cantidad.
Editar: también debe proporcionar una función
Foo.prototype.unregisterInstance = function() {
delete store[this.__guid];
};
De lo contrario, esta es una buena forma de introducir una pérdida de memoria ...
Edit2: también puede evitar la necesidad de una función registerInstance()
con el siguiente patrón:
Foo = (function() {
var store = {}, guid = 0;
function Foo() {
this.__guid = ++guid;
store[guid] = { bar : ''baz'' };
}
Foo.prototype.getBar = function() {
var privates = store[this.__guid];
return privates.bar;
};
Foo.prototype.destroy = function() {
delete store[this.__guid];
};
return Foo;
})();
Encontrará mucha gente usando el
function name()
{
var m_var = null;
var privateMethod = function() { }
this.PublicMethod = function() { }
}
Incluyéndome a mi. Tiendo a no escribir grandes clases de JS y esta sintaxis es bastante fácil de escribir y también permite métodos / variables privados.
EDITAR
Así que me dice que usar XML para paquetes SOAP solo para facilitar la depuración un paso es correcto (aunque XML desperdicia un BUNCH de espacio y ancho de banda, y análisis de tiempo), pero agregar algunos bytes por instancia de objeto JavaScript no está bien, incluso si ¿nos permite utilizar algunos de los conceptos básicos de OO que deberían existir en el lenguaje desde el principio?
Hmm ...
(para mi comentario XML, lea los comentarios sobre: REST URI y operaciones en un objeto que puede ser comentado, etiquetado, calificado, etc. )