herencia es6 javascript oop

es6 - javascript prototype constructor



Clásica Vs herencia prototípica (3)

Como Javascript no admite la herencia "clásica" como la mayoría lo entendería (y no ha proporcionado ninguna referencia a lo que ha estado leyendo), asumiré que se refiere a la herencia que se maneja de esta manera:

function base() { var myVar; this.someBaseFunc = function() { } } function derived() { base.call(this); var someOtherVar; this.SomeOtherFunc = function() { } }

Mi regla general es:

  • Si las clases son complejas y las instancias son pocas, utilice un enfoque "clásico". Esto permite a las clases exponer públicamente solo aquellas características que deberían hacerse públicas.
  • Si la Clase es simple y las instancias son muchas, utilice un enfoque prototípico. Esto limita la sobrecarga de definir y almacenar referencias a funciones una y otra vez a medida que se crean las instancias.

Después de leer sobre ambos, tengo curiosidad, ¿cómo la comunidad de programación usa esto? ¿En qué situación cuál?


Hay muchos problemas con la herencia clásica que no existen con la herencia prototípica, como:

Herencia clásica

Acoplamiento apretado . La herencia es el acoplamiento más estrecho disponible en el diseño OO. Las clases descendientes tienen un conocimiento íntimo de sus clases de antepasados.

Jerarquías inflexibles (aka duplicación por necesidad) . Las jerarquías de un solo padre rara vez son capaces de describir todos los posibles casos de uso. Eventualmente, todas las jerarquías son "incorrectas" para nuevos usos, un problema que requiere la duplicación de código.

La herencia múltiple es complicada . A menudo es deseable heredar de más de un padre. Ese proceso es excesivamente complejo y su implementación es inconsistente con el proceso de herencia simple, lo que dificulta su lectura y comprensión.

La arquitectura frágil . Debido al acoplamiento apretado, a menudo es difícil refactorizar una clase con el diseño "incorrecto", porque gran parte de la funcionalidad existente depende del diseño existente.

El problema del gorila / banano . A menudo, hay partes del padre que no desea heredar. La subclasificación le permite anular las propiedades del padre, pero no le permite seleccionar las propiedades que desea heredar.

Herencia prototípica

Para comprender cómo la herencia prototípica resuelve estos problemas, primero debe comprender que existen dos tipos diferentes de herencia prototípica. JavaScript soporta ambos:

Delegación . Si una propiedad no se encuentra en una instancia, se busca en el prototipo de la instancia. Esto le permite compartir métodos entre muchos casos, lo que le da el patrón de peso mosca de forma gratuita .

La concatenacion La capacidad de agregar dinámicamente propiedades a un objeto le permite copiar libremente cualquier propiedad de un objeto a otro, de forma conjunta o selectiva.

Puede combinar ambas formas de herencia prototípica para lograr un sistema muy flexible de reutilización de código. Tan flexible de hecho, que es trivial implementar la herencia clásica con prototipos. Lo opuesto no es verdad.

La herencia prototípica permite la mayoría de las características importantes que encontrará en los idiomas clásicos. En JavaScript, los cierres y las funciones de fábrica le permiten implementar un estado privado, y la herencia funcional se puede combinar fácilmente con prototipos para agregar combinaciones que también admitan la privacidad de los datos.

Algunas ventajas de la herencia prototípica:

Acoplamiento suelto . Una instancia nunca tiene la necesidad de hacer una referencia directa a una clase principal o prototipo. Es posible almacenar una referencia al prototipo de un objeto, pero no es aconsejable, ya que eso promovería el acoplamiento estrecho en la jerarquía de objetos, uno de los mayores escollos de la herencia clásica.

Jerarquías planas . Es trivial con el OO prototípico mantener las jerarquías de herencia planas: mediante concatenación y delegación, puede tener un solo nivel de delegación de objetos y una sola instancia, sin referencias a las clases primarias.

Herencia múltiple trivial . Heredar de varios ancestros es tan fácil como combinar propiedades de múltiples prototipos utilizando la concatenación para formar un nuevo objeto, o un nuevo delegado para un nuevo objeto.

Arquitectura flexible . Ya que puede heredar selectivamente con OO prototípico, no tiene que preocuparse por el problema del "diseño incorrecto". Una nueva clase puede heredar cualquier combinación de propiedades de cualquier combinación de objetos de origen. Debido a la facilidad de aplanamiento de la jerarquía, un cambio en un lugar no necesariamente causa ondulaciones en una larga cadena de objetos descendientes.

No más gorilas . La herencia selectiva elimina el problema del banano gorila.

No tengo conocimiento de ninguna ventaja que tenga la herencia clásica sobre la herencia prototípica. Si alguien está al tanto de alguna, por favor, ilumíname.


La herencia basada en prototipos es más flexible. Cualquier objeto existente puede convertirse en una clase a partir de la cual se generarán objetos adicionales. Esto es útil cuando sus objetos ofrecen varios conjuntos de servicios y / o se someten a una gran cantidad de transformación de estado antes de que su programa llegue al punto donde se necesita la herencia.

Una discusión de amplio espectro de enfoques de modelado está disponible aquí: http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html