Los prototipos son una optimización .
Un gran ejemplo de cómo usarlos bien es la biblioteca jQuery. Cada vez que obtiene un objeto jQuery utilizando $('.someClass')
, ese objeto tiene docenas de "métodos". La biblioteca podría lograr eso devolviendo un objeto:
return {
show: function() { ... },
hide: function() { ... },
css: function() { ... },
animate: function() { ... },
// etc...
};
Pero eso significaría que cada objeto jQuery en la memoria tendría docenas de ranuras con nombre que contienen los mismos métodos, una y otra vez.
En cambio, esos métodos se definen en un prototipo y todos los objetos jQuery "heredan" ese prototipo para obtener todos esos métodos a un costo de ejecución muy bajo.
Una parte de vital importancia de cómo jQuery lo hace bien es que esto está oculto al programador. Se trata simplemente como una optimización, no como algo de lo que tenga que preocuparse cuando use la biblioteca.
El problema con JavaScript es que las funciones de constructor desnudas requieren que la persona que llama recuerde ponerles un prefijo new
o, de lo contrario, normalmente no funcionan. No hay una buena razón para ello. jQuery lo hace bien al ocultar esas tonterías detrás de una función ordinaria $
, por lo que no tiene que preocuparse de cómo se implementan los objetos.
Para que pueda crear cómodamente un objeto con un prototipo específico, ECMAScript 5 incluye una función estándar Object.create
. Una versión muy simplificada se vería así:
Object.create = function(prototype) {
var Type = function () {};
Type.prototype = prototype;
return new Type();
};
Simplemente se encarga del dolor de escribir una función constructora y luego llamarla con new
.
¿Cuándo evitarías los prototipos?
Una comparación útil es con lenguajes de OO populares como Java y C #. Estos admiten dos tipos de herencia:
- interfaz de la herencia, en el que
implement
un interface
tal que la clase proporciona su propia implementación única para cada miembro de la interfaz.
- aplicación de herencia, en el que
extend
una class
que proporciona implementaciones por defecto de algunos métodos.
En JavaScript, la herencia prototípica es una especie de herencia de implementación . Entonces, en aquellas situaciones en las que (en C # o Java) habría derivado de una clase base para obtener el comportamiento predeterminado, al que luego realiza pequeñas modificaciones a través de anulaciones, luego en JavaScript, la herencia prototípica tiene sentido.
Sin embargo, si se encuentra en una situación en la que habría utilizado interfaces en C # o Java, entonces no necesita ninguna característica de lenguaje en particular en JavaScript. No es necesario declarar explícitamente algo que represente la interfaz, y no es necesario marcar los objetos como "implementando" esa interfaz:
var duck = {
quack: function() { ... }
};
duck.quack(); // we're satisfied it's a duck!
En otras palabras, si cada "tipo" de objeto tiene sus propias definiciones de los "métodos", entonces no tiene ningún valor heredar de un prototipo. Después de eso, depende de cuántas instancias asigne de cada tipo. Pero en muchos diseños modulares, solo hay una instancia de un tipo determinado.
Y de hecho, muchas personas han sugerido que la herencia de implementación es mala . Es decir, si hay algunas operaciones comunes para un tipo, entonces tal vez sea más claro si no se colocan en una clase base / super, sino que se exponen como funciones ordinarias en algún módulo, al que se le pasa el objeto (s) desea que operen.
quack
función esté en un prototipo, al que están vinculadas las muchas instancias de pato. 2. La sintaxis literal del objeto{ ... }
crea una instancia (no es necesario utilizarlanew
). 3. Llamar a cualquier función JS hace que se cree al menos un objeto en la memoria - se llama elarguments
objeto y almacena los argumentos pasados en la llamada: developer.mozilla.org/en/JavaScript/Reference/…Debería utilizar prototipos si desea declarar un método "no estático" del objeto.
fuente
this
ejemplothis.getA = function(){alert("A")}
¿verdad?Una razón para usar el
prototype
objeto integrado es si va a duplicar un objeto varias veces que compartirá una funcionalidad común. Al adjuntar métodos al prototipo, puede ahorrar en la creación de métodos duplicados para cadanew
instancia. Pero cuando adjunta un método alprototype
, todas las instancias tendrán acceso a esos métodos.Digamos que tiene una
Car()
clase / objeto base .luego crea varias
Car()
instancias.Ahora, sabe que cada automóvil deberá conducir, encender, etc. En lugar de adjuntar un método directamente a la
Car()
clase (que ocupa memoria por cada instancia creada), puede adjuntar los métodos al prototipo (creando los métodos solo once), dando acceso a esos métodos tanto al nuevovolvo
como asaab
.fuente
Car.prototype = { ... }
tuviera que mantener este ejemplo como está, tendría que venir antes de llamar anew Car()
como se ilustra en este jsfiddle: jsfiddle.net/mxacA . En cuanto a su argumento, esta sería la forma correcta de hacerlo: jsfiddle.net/Embnp . Lo curioso es que no recuerdo haber respondido esta pregunta =)Coloque funciones en un objeto prototipo cuando vaya a crear muchas copias de un tipo particular de objeto y todas necesiten compartir comportamientos comunes. Al hacerlo, ahorrará algo de memoria al tener solo una copia de cada función, pero ese es solo el beneficio más simple.
Cambiar métodos en objetos prototipo, o agregar métodos, cambia instantáneamente la naturaleza de todas las instancias del tipo (s) correspondiente (s).
Ahora, exactamente por qué haría todas estas cosas es principalmente una función del diseño de su propia aplicación y el tipo de cosas que necesita hacer en el código del lado del cliente. (Una historia completamente diferente sería el código dentro de un servidor; mucho más fácil de imaginar haciendo más código "OO" a gran escala allí).
fuente
Si explico en el término basado en la clase, entonces Person es clase, walk () es el método Prototype. Así que walk () tendrá su existencia solo después de crear una instancia de un nuevo objeto con esto.
Entonces, si desea crear copias de objetos como Persona u, puede crear muchos usuarios. El prototipo es una buena solución, ya que ahorra memoria al compartir / heredar la misma copia de función para cada uno de los objetos en la memoria.
Mientras que la estática no es de gran ayuda en tal escenario.
Entonces, con esto es más parecido al método de instancia. El enfoque del objeto es como los métodos estáticos.
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
fuente