OOP en JavaScript
El OOP en JavaScript esta implementado por prototipos, aun asi, sigue los cuatro principios basicos:
- Abstraccion. Trae los detalles relevantes ignorando lo que no nnos interesa
- Encapsulacion
- Herencia
- Polimorfismo
Existen tres forma de implementar el OOP basado en prototipos (delegacion) en JS:
- Constructores. Crear objetos desde una funcion
- ES6 Classes. Sintactic sugar que utiliza la anterior para crear pero que hace que resulte mas comodo usar la OOP
- Object.create(). La funcion mas rapida de vincuilar un objeto a un prototipo
# Funcion Constructor
Son funciones normales, la unica diferencia esque para llamar un constructor utilizamos “new”.
| |
Al utilizar esta forma ocurre lo siguiente:
- Se crea un nuevo objeto
- Se llama a la funcion constructora(con parametros y todo)
- La keyword “this” se asigna a este objeto creado en el contexto de la funcion
- El objeto se vincula a un prototipo
- El objeto se retorna de la funcion
# Prototipos
Para resumir, una funcion (TODAS) siempre tienen una propiedad llamada “prototype”, incluidas las funciones constructoras. Por defecto, una funcion constructora dara acceso a todos los atributos y metodos definidos en el prototipo a sus instancias.
| |
Haciendolo de esta forma, todos los objetos que sean instanciados mediante la funcion constructora “Person” acceden a la funcion del prototipo. Asi mismo, cada uno de los objetos puede utilizar sus atributos dentro de los prototipos.
# Prototype Chain
Una serie de uniones entre objetos y sus prototipos. Esta termina cuando se llega a Object.prototype, el cual es null.

Como dato curioso la sintaxis de corchetes {} es un shorthand para crear un objecto con la funcion constructora “Object”, es decir, los siguientes son equivalentes:
| |
# Clases de ES6
Las clases en JavaScript no trabajan como en otros lenguajes, unicamente son sintaxis que utiliza los mecanismos anteriores para trabajar.
Es bastante parecida a la sintaxis de Java
| |
- Las clases NO son hoisted
- Las clases son first-class-citizens
- Las clases son SIEMPRE ejecutadas usando ‘strict mode’
# Setters y Getters
Son dos funciones especiales que podemos declarar en nuestros objetos en JavaScript. Son funciones que para el mundo externo les parecen como si fueran propiedades.
| |
Para acceder a ellos, unicamente se leen como una propiedad
| |
Finalmente, estas tambien pueden ser utilizadas dentro de nuestras clases
| |
Error si tienes el mismo atributo en el constructor y el setter. Se reventara el callstack debido a que se llamara en un loop infinito el uno a la otra. Para corregir esto la convencion es utilizar una nueva propiedad dentro del setter:
| |
# Metodos estaticos
Son metodos que se encuentran unidos escencialmente a una clase, en el caso de JavaScript, se encuentran como parte de la funcion constructora.
Un ejemplo de estas son las siguientes funciones:
| |
Recordando que todo son objetos en JavaScript, puedes añadirle metodos a una funcion constructora
| |
Y estos a su vez no seran heredados debido a que no se encuentran en el prototipo!.
En el caso de las clases de ES6 tenemos la sintaxis especial de ‘static’
| |
# Object.create
Esta es la tercera forma de implementar OOP en JavaScript.
Se conserva la idea de los prototipos pero sin la presencia de las propiedades, mediante esta, podemos crear un object literal que sirva como prototipo para todos y posteriormente asignarlo como prototipo usando la funcion Object.create.
| |
La diferencia con las funciones constructoras esque, como se ve, en este caso estamos asignando de manera manual el prototipo del objeto. Caso contrario a las funciones constructoras donde estas lo hacen de forma automatica.
# Herencia
Para establecer una tipica herencia de la OOP en JavaScript debemos utilizar el asignador de prototipos (Object.create). Mediante este, podemos asignar el prototipo de un objeto.
Para lograr la herencia, debemos hacer que el prototipo de la funcion constructora de la subclase apunte al prototipo de la funcion constructora de la superclase.
| |
Finalmente, algo que debemos hacer es corregir el side effect que tiene Object.create, y esque esta funcion actualiza el constructor del prototipo de la subclase para que sea el constructor de la superclase, para corregirlo:
| |

Con esto, debemos tener el Prototype Chain bien asignado.
Finalmente, para crear una instancia primero se debe llamar el constructor de la superclase para que se coloquen las propiedades correctamente. Para esto, utilizaremos el metodo especial .call del prototipo funcion que nos permite asignar ’this’ dentro del scope de cada funcion:
| |
Como conclusion, el prototype chain nos sirve para establecer la cadena de herencias en JavaScript.
# Herencia entre Clases Sintaxis ES6
Existe una forma mucho mas parecida a Java y mucho mas facil para implementar la herencai entre clases, esta utiliza de las keywords “extends” y la funcion “super()”.
| |
Con solo esto, todo el prototype chain, y funciones constructoras se coloca de forma adecuada.
# Herencia con Object.create
Para hacer una herencia entre los prototipos de los objetos basta con introducir una nueva clase a la Prototype Chain
| |
Podemos aprovechar nuevamente “call” para llamar los metodos del Prototipo de Person con “this” actualizada
| |
# Encapsulamiento
En JavaScript podemos implementar un tipo de encapsulamiento a nuestros atributos:
- private (Disponible solo para la clase)
La sintaxis en JavaScript es utilizar ‘#’:
| |
# Resumen
