script programación programacion poo polimorfismo orientada objetos herencia es6 ejercicios javascript oop functional-programming polymorphism parametric-polymorphism

programación - ¿Qué es el polimorfismo en Javascript?



programacion orientada a objetos javascript (6)

¿Qué es?

Poli = muchos, morfismo = cambio de forma o comportamiento.

¿Por qué lo necesitamos?

En programación, se usa cuando queremos que la interfaz de una función (digamos la función X) sea lo suficientemente flexible como para aceptar diferentes tipos o cantidad de parámetros. Además, según el cambio de los tipos o números de parámetros, es posible que queramos que la función X se comporte de manera diferente (morfismo).

¿Cómo funciona?

Escribimos múltiples implementaciones de la función X donde cada implementación acepta diferentes tipos de parámetros o número de parámetros. Según el tipo o número de parámetro, el compilador (en tiempo de ejecución) decide qué implementación de X debe ejecutarse cuando se llama a X desde algún código.

¿Cómo puedo lograr este comportamiento polimórfico en JavaScript?

JS no es un lenguaje mecanografiado, por lo que realmente no está destinado a usar conceptos de POO como el polimorfismo. Sin embargo, la versión más nueva de JS ahora incluye clases y existe la posibilidad de que el polimosfismo también comience a tener sentido en JS. Otras respuestas proporcionan algunas soluciones interesantes.

He leído algunos artículos posibles que pude encontrar en Internet sobre polimorfismo . Pero creo que no pude comprender el significado y su importancia. La mayoría de los artículos no dicen por qué es importante y cómo puedo lograr un comportamiento polimórfico en OOP (por supuesto, en JavaScript).

No puedo proporcionar ningún ejemplo de código porque no tengo la idea de cómo implementarlo, por lo que mis preguntas están a continuación:

  1. ¿Qué es?
  2. ¿Por qué lo necesitamos?
  3. ¿Cómo funciona?
  4. ¿Cómo puedo lograr este comportamiento polimórfico en javascript?

Tengo este ejemplo. Pero es fácilmente comprensible cuál será el resultado de este código. No da ninguna idea clara sobre el polimorfismo en sí.

function Person(age, weight) { this.age = age; this.weight = weight; this.getInfo = function() { return "I am " + this.age + " years old " + "and weighs " + this.weight +" kilo."; } } function Employee(age, weight, salary) { this.salary = salary; this.age = age; this.weight = weight; this.getInfo = function() { return "I am " + this.age + " years old " + "and weighs " + this.weight +" kilo " + "and earns " + this.salary + " dollar."; } } Employee.prototype = new Person(); Employee.prototype.constructor = Employee; // The argument, ''obj'', can be of any kind // which method, getInfo(), to be executed depend on the object // that ''obj'' refer to. function showInfo(obj) { document.write(obj.getInfo() + "<br>"); } var person = new Person(50,90); var employee = new Employee(43,80,50000); showInfo(person); showInfo(employee);


¿Cuál es el propósito del polimorfismo?

El polimorfismo hace que un sistema de tipo estático sea más flexible sin perder la seguridad de tipo estático (significativo) al aflojar las condiciones para la equivalencia de tipo. La prueba es que un programa solo se ejecutará si no contiene ningún tipo de error.

Una función polimórfica o tipo de datos es más general que una monomórfica, porque puede usarse en una gama más amplia de escenarios. En este sentido, el polimorfismo representa la idea de generalización en lenguajes estrictamente tipados.

¿Cómo se aplica esto a Javascript?

Javascript tiene un sistema de tipo débil y dinámico. Tal sistema de tipos es equivalente a un sistema de tipos estricto que contiene solo un tipo. Podemos pensar en ese tipo como un tipo de unión enorme (pseudo sintaxis):

type T = | Undefined | Null | Number | String | Boolean | Symbol | Object | Array | Map | ...

Cada valor estará asociado a una de estas alternativas de tipo en tiempo de ejecución. Y dado que Javascript tiene un tipo débil, cada valor puede cambiar su tipo varias veces.

Si tomamos una perspectiva teórica de tipos y consideramos que solo hay un tipo, podemos decir con certeza que el sistema de tipos de Javascript no tiene una noción de polimorfismo. En cambio, tenemos la escritura de pato y la coerción de tipo implícita.

Pero esto no debería evitar que pensemos en los tipos en nuestros programas. Debido a la falta de tipos en Javascript, debemos inferirlos durante el proceso de codificación. Nuestra mente tiene que sustituir al compilador perdido, es decir, tan pronto como veamos un programa, debemos reconocer no solo los algoritmos, sino también los tipos subyacentes (tal vez polimórficos). Estos tipos nos ayudarán a construir programas más confiables y más robustos.

Para hacer esto correctamente, le daré una visión general de las manifestaciones más comunes del polimorfismo.

Polimorfismo paramétrico (también conocido como genéricos)

El polimorfismo paramétrico dice que los diferentes tipos son intercambiables porque los tipos no importan en absoluto. Una función que define uno o más parámetros de tipo polimórfico paramétrico no debe saber nada sobre los argumentos correspondientes sino tratarlos de la misma manera, ya que pueden adoptar cualquier tipo. Esto es bastante restrictivo, porque dicha función solo puede funcionar con aquellas propiedades de sus argumentos que no son parte de sus datos:

// parametric polymorphic functions const id = x => x; id(1); // 1 id("foo"); // "foo" const k = x => y => x; const k_ = x => y => y; k(1) ("foo"); // 1 k_(1) ("foo"); // "foo" const append = x => xs => xs.concat([x]); append(3) ([1, 2]); // [1, 2, 3] append("c") (["a", "b"]); // ["a", "b", "c"]

Polimorfismo ad-hoc (también conocido como sobrecarga)

El polimorfismo ad-hoc dice que los diferentes tipos son equivalentes solo para un propósito específico. Para ser equivalente en este sentido, un tipo debe implementar un conjunto de funciones específicas para ese propósito. Una función que define uno o más parámetros de tipo polimórfico ad-hoc necesita saber qué conjuntos de funciones están asociados a cada uno de sus argumentos.

El polimorfismo ad-hoc hace que una función sea compatible con un dominio de tipos más grande. El siguiente ejemplo ilustra el propósito del "mapeo" y cómo los tipos pueden implementar esta restricción. En lugar de un conjunto de funciones, la restricción "asignable" solo incluye una única función de map :

// Option type class Option { cata(pattern, option) { return pattern[option.constructor.name](option.x); } map(f, opt) { return this.cata({Some: x => new Some(f(x)), None: () => this}, opt); } }; class Some extends Option { constructor(x) { super(x); this.x = x; } }; class None extends Option { constructor() { super(); } }; // ad-hoc polymorphic function const map = f => t => t.map(f, t); // helper/data const sqr = x => x * x; const xs = [1, 2, 3]; const x = new Some(5); const y = new None(); // application console.log( map(sqr) (xs) // [1, 4, 9] ); console.log( map(sqr) (x) // Some {x: 25} ); console.log( map(sqr) (y) // None {} );

Subtipo de polimorfismo

Como otras respuestas ya cubren el polimorfismo de subtipo, lo omito.

Polimorfismo estructural (también conocido como subtipo estructural)

El polimorfismo estructural dice que los diferentes tipos son equivalentes, si contienen la misma estructura de tal manera, que un tipo tiene todas las propiedades del otro pero puede incluir propiedades adicionales. Dicho esto, el polimorfismo estructural es tipear patos en tiempo de compilación y ciertamente ofrece cierta seguridad adicional de tipo. Pero al afirmar que dos valores son del mismo tipo solo porque comparten algunas propiedades, ignora por completo el nivel semántico de los valores:

const weight = {value: 90, foo: true}; const speed = {value: 90, foo: false, bar: [1, 2, 3]};

Desafortunadamente, la speed se considera un subtipo de weight y tan pronto como comparamos las propiedades de value , estamos comparando virtualmente las manzanas con las naranjas.


Como se explica en esta otra respuesta , el polimorfismo tiene diferentes interpretaciones.

La mejor explicación sobre el tema que he leído es un artículo de Luca Cardelli , un reconocido teórico del tipo. El artículo se llama Sobre tipos de comprensión, abstracción de datos y polimorfismo .

¿Qué es?

Cardelli define varios tipos de polimorfismo en este artículo:

  • Universal
    • paramétrico
    • inclusión
  • Ad hoc
    • volando
    • coerción

Quizás en JavaScript, es un poco más difícil ver los efectos del polimorfismo porque los tipos más clásicos de polimorfismo son más evidentes en los sistemas de tipo estático, mientras que JavaScript tiene un sistema de tipo dinámico.

Entonces, por ejemplo, no hay sobrecarga de método o función o coacciones de tipo automático en tiempo de compilación en JavaScript. En un lenguaje dinámico, damos por sentado la mayoría de estas cosas. Tampoco necesitamos algo como el polimorfismo paramétrico en JavaScript debido a la naturaleza dinámica del lenguaje.

Aún así, JavaScript tiene una forma de herencia de tipo que emula las mismas ideas de polimorfismo de subtipo (clasificado como polimorfismo de inclusión por Cardelli arriba) de una manera similar a lo que solemos hacer en otros lenguajes de programación orientados a objetos como Java o C # (como se explica en otra respuesta que compartí arriba).

Otra forma de polimorfismo muy típica en lenguajes dinámicos se llama tipificación de pato .

Es un error creer que el polimorfismo solo está relacionado con la programación orientada a objetos. Otros modelos de programación (funcional, de procedimiento, lógica, etc.) ofrecen diferentes formas de polimorfismo en sus sistemas de tipos, probablemente de una manera un poco desconocida para aquellos que solo están acostumbrados a OOP.

¿Por qué lo necesitamos?

El polimorfismo fomenta muchos buenos atributos en el software, entre otras cosas, fomenta la modularidad y la reutilización y hace que el sistema de tipos sea más flexible y maleable. Sin ella, sería muy difícil razonar sobre los tipos. El polimorfismo asegura que un tipo pueda ser sustituido por otros compatibles, siempre que satisfagan una interfaz pública, por lo que esto también fomenta la ocultación de la información y la modularidad.

¿Como funciona?

Esto no es fácil de responder, los diferentes idiomas tienen diferentes formas de implementarlo. En el caso de JavaScript, como se mencionó anteriormente, verá que se materializa en forma de jerarquías de tipos usando herencia prototípica y también puede explotarlo usando la escritura de pato.

El tema es un poco amplio y abriste dos preguntas en una sola publicación. Quizás sea mejor que comience leyendo el documento de Cardelli y luego intente comprender el polimorfismo independientemente de cualquier lenguaje o paradigma de programación, luego comenzará a hacer asociaciones entre los conceptos teóricos y lo que cualquier lenguaje particular como JavaScript tiene para ofrecer para implementar esas ideas.


El polimorfismo es uno de los principios de la programación orientada a objetos (OOP). Es la práctica de diseñar objetos para compartir comportamientos y poder anular comportamientos compartidos con otros específicos. El polimorfismo aprovecha la herencia para que esto suceda.

En OOP, todo se considera modelado como un objeto. Esta abstracción se puede llevar hasta los topes para un automóvil, o tan amplia como simplemente un tipo de automóvil con un año, marca y modelo.

Para tener un escenario de automóvil polimórfico, existiría el tipo de automóvil base, y luego habría subclases que heredarían del automóvil y proporcionarían sus propios comportamientos además de los comportamientos básicos que tendría un automóvil. Por ejemplo, una subclase podría ser TowTruck, que todavía tendría un año de marca y modelo, pero también podría tener algunos comportamientos y propiedades adicionales que podrían ser tan básicos como una bandera para IsTowing y tan complicados como los detalles específicos del ascensor.

Volviendo al ejemplo de las personas y los empleados, todos los empleados son personas, pero no todas las personas son empleados. Es decir que las personas serán la superclase y los empleados la subclase. Las personas pueden tener edades y pesos, pero no tienen salarios. Los empleados son personas, por lo que tendrán una edad y un peso inherentes, pero también porque son empleados tendrán un salario.

Entonces, para facilitar esto, primero escribiremos la superclase (Persona)

function Person(age,weight){ this.age = age; this.weight = weight; }

Y le daremos a la Persona la capacidad de compartir su información

Person.prototype.getInfo = function(){ return "I am " + this.age + " years old " + "and weighs " + this.weight +" kilo."; };

Luego deseamos tener una subclase de Persona, Empleado

function Employee(age,weight,salary){ this.age = age; this.weight = weight; this.salary = salary; } Employee.prototype = new Person();

Y anularemos el comportamiento de getInfo definiendo uno que sea más apropiado para un Empleado

Employee.prototype.getInfo = function(){ return "I am " + this.age + " years old " + "and weighs " + this.weight +" kilo " + "and earns " + this.salary + " dollar."; };

Se pueden usar de manera similar al uso de su código original

var person = new Person(50,90); var employee = new Employee(43,80,50000); console.log(person.getInfo()); console.log(employee.getInfo());

Sin embargo, no se gana mucho usando la herencia aquí, ya que el constructor de Employee es muy similar al de la persona, y la única función en el prototipo se está anulando. El poder en el diseño polimórfico es compartir comportamientos.


JavaScript es un lenguaje interpretado, no un lenguaje compilado.

Polimorfismo en tiempo de compilación (o polimorfismo estático) El polimorfismo en tiempo de compilación no es más que el método de sobrecarga en Java, C ++

Por lo tanto, la sobrecarga de métodos no es posible en JavaScript.

Pero el polimorfismo dinámico (tiempo de ejecución) es el polimorfismo existente en tiempo de ejecución, por lo que es posible anular el método en JavaScript

Otro ejemplo es PHP.


Polimorfismo significa la capacidad de llamar al mismo método en diferentes objetos y cada objeto responde de manera diferente se llama POLIMORFISMO .

function Animal(sound){ this.sound=sound; this.speak=function(){ return this.sound; } } //one method function showInfo(obj){ console.log(obj.speak()); } //different objects var dog = new Animal("woof"); var cat = new Animal("meow"); var cow = new Animal("humbow"); //responds different ways showInfo(dog); showInfo(cat); showInfo(cow);