ejemplos - Pseudo-clásico vs. “El camino de JavaScript”
javascript html (4)
Acabo de terminar de leer " JavaScript: The Good Parts " de Crockford y tengo una pregunta con respecto a su postura sobre los enfoques pseudo-clásicos y prototípicos. En realidad no estoy realmente interesado en su postura; Solo quiero entender su argumento para poder establecer una postura propia.
En el libro, Crockford parece inferir que las funciones de constructor y "todo ese jazz" no se deben usar en JavaScript. Menciona cómo la palabra clave ''nuevo'' está mal implementada, es decir, las funciones que no son de Constructor pueden llamarse con el ''nuevo'' palabra clave y viceversa (potencialmente causando problemas).
Pensé que entendía de dónde venía, pero supongo que no.
Cuando necesito crear un nuevo módulo, normalmente comenzaría así:
function MyModule(something) {
this.something = something || {};
}
Y luego agregaría algunos métodos a su prototipo:
MyModule.prototype = {
setSomething : function(){},
getSomething : function(){},
doSomething : function(){}
}
Me gusta este modelo; significa que puedo crear una nueva instancia cada vez que la necesite y tiene sus propias propiedades y métodos:
var foo = new MyModule({option1: ''bar''});
// Foo is an object; I can do anything to it; all methods of the "class"
// are available to this instance.
Mi pregunta es : ¿Cómo puedo lograr lo anterior utilizando un enfoque más adecuado para JavaScript? En otras palabras, si "JavaScript" fuera una persona, ¿qué sugeriría ella?
También: ¿Qué quiere decir Crockford cuando dice que un patrón de diseño particular "es más expresivo" y luego otro?
Consulte: ¿Se considera dañina la palabra "nueva" de JavaScript?
Es importante recordar que Crockford, al igual que muchos otros programadores de JavaScript, se acercó al lenguaje con el objetivo de "arreglarlo", haciéndolo más como otros idiomas (O "clásico") OO. Así que se escribió una gran cantidad de código estructural, se construyeron bibliotecas y marcos, y ... luego comenzaron a darse cuenta de que realmente no era necesario; Si te acercas a JS en sus propios términos, puedes llevarte bien.
Javascript no es una persona, así que realmente no puede sugerir lo que haces.
Ninguna de las respuestas anteriores ha mencionado el estilo funcional de herencia simple, que tiendo a encontrar es el más simple.
function myModuleMaker(someProperty){
var module = {}; //define your new instance manually
module.property = someProperty; //set your properties
module.methodOne = function(someExternalArgument){
//do stuff to module.property, which you can, since you have closure scope access
return module;
}
}
Ahora para hacer una nueva instancia:
var newModule = myModuleMaker(someProperty);
Aún así, obtienes todos los beneficios de pseudoclásico, pero tienes el único inconveniente de que estás haciendo una nueva copia de todos los métodos de tu instancia cada vez que creas una instancia. Probablemente esto solo será importante cuando empieces a tener muchos cientos (o incluso miles) de instancias, lo cual es un problema que la mayoría de las personas rara vez se encuentra. Estará mejor con pseudoclásico si está creando estructuras de datos realmente enormes o haciendo animaciones de núcleo duro con muchas, muchas instancias de algo.
Creo que es difícil argumentar que cualquiera de los métodos es una "mala práctica" per se.
La variante prototípica para el ejemplo que tiene se parece a la siguiente:
Object.beget = function (o) { /* Crockfords replacement for the new */ }
var myModule = {
something : null,
getSomething : function () {},
setSomething : function () {},
doSomething : function () {}
};
Y luego puedes hacer:
var foo = Object.beget(myModule);
foo.something = bar;
ACTUALIZACIÓN: También puede usar el patrón de constructor para reemplazar un constructor como este:
var myModuleBuilder = {
buildMyModule : function (something) {
var m = Object.beget(myModule);
m.something = something || {};
return m;
}
}
entonces puedes hacer
var foo = myModuleBuilder.buildMyModule(something);
Su implementación es problemática porque está reemplazando el objeto prototipo completo, perdiendo las propiedades del prototipo de función heredada y también rompería, o al menos haría más difícil, la capacidad de hacer uso de la herencia más adelante si escribió otras clases. de la misma manera
Un método más adecuado para Javascript sería:
var MyClass = function (storeThis) {
this.storage = storeThis
}
MyClass.prototype.getStorage = function (){
return this.storage;
}
MyClass.prototype.setStorage = function (newStorage){
this.storage = newStorage;
}
Úsalo:
var myInstance = new MyClass("sup");
alert("myInstance storage: " + myInstance.getStorage());
myInstance.setStroage("something else");
En cuanto a la "nueva" palabra clave y los problemas de Crawford con ella, realmente no puedo responder, porque no he leído el libro, pero puedo ver cómo podría crear un nuevo objeto llamando a cualquier función con la nueva palabra clave, incluyendo Funciones que se supone que son métodos de una clase.
Y cuando alguien dice algo, como un patrón de diseño, es más "expresivo", él o ella generalmente significa que el patrón de diseño es claro y fácil de entender en cuanto a lo que está logrando y cómo.