JS, Node.js, Frontend, Backend, Firebase, Express, Patrones, HTML5_APIs, Asincronía, Websockets, Testing
Un paradigma de programación es una propuesta tecnológica adoptada por una comunidad de programadores y desarrolladores cuyo núcleo central es incuestionable en cuanto que únicamente trata de resolver uno o varios problemas claramente delimitados; la resolución de estos problemas debe suponer consecuentemente un avance significativo en al menos un parámetro que afecte a la ingeniería de software. Un paradigma de programación representa un enfoque particular o filosofía para diseñar soluciones. Los paradigmas difieren unos de otros, en los conceptos y la forma de abstraer los elementos involucrados en un problema, así como en los pasos que integran su solución del problema, en otras palabras, el cómputo. Tiene una estrecha relación con la formalización de determinados lenguajes en su momento de definición. Es un estilo de programación empleado. Un paradigma de programación está delimitado en el tiempo en cuanto a aceptación y uso, porque nuevos paradigmas aportan nuevas o mejores soluciones que la sustituyen parcial o totalmente. Wikipedia
Paradigmas principales
- Programación imperativa o por procedimientos
- Extendida en C, BASIC o Pascal.
- La programación imperativa es la más usada y la más antigua
- Se basa en dar instrucciones al ordenador de como hacer las cosas en forma de algoritmos.
- Programación orientada a objetos (POO/OOP)
- Extendida en C++, C#, Java, Python...
- Está basada en el imperativo, pero encapsula elementos denominados objetos que incluyen tanto variables como funciones
- Programación dirigida por eventos
- Tanto la estructura como la ejecución de los programas van determinados por los sucesos que ocurran en el sistema, definidos por el usuario o que ellos mismos provoquen.
- Programación funcional
- Basada en la definición los predicados
- Es de corte más matemático
- Extendida en Python, Haskell, etc...
- Programación reactiva
- Este paradigma se basa en la declaración de una serie de objetos emisores de eventos asíncronos y otra serie de objetos que se "suscriben" a los primeros (es decir, quedan a la escucha de la emisión de eventos de estos) y reaccionan a los valores que reciben.
- Es muy común usar la librería Rx de Microsoft (Reactive Extensions)
- Programación multiparadigma
- Es el uso de dos o más paradigmas dentro de un programa.
Otros paradigmas
- Programación declarativa
- Lenguaje específico del dominio (DSL): SQL
- Programación con restricciones
- Programación lógica
- Programación dinámica
- Etc...
La programación basada en prototipos es un estilo de programación orientada a objetos en la que las clases no están presentes y la reutilización de comportamiento (conocido como herencia en lenguajes basados en clases) se lleva a cabo a través de un proceso de decoración de objetos existentes que sirven de prototipos. Este modelo también se conoce como programación sin clases, orientada a prototipos o basada en ejemplos. Mozilla developer network
Terminología
- Clase
- Define las características del Objeto.
- Objeto
- Una instancia de una Clase.
- Propiedad
- Una característica del Objeto, como el color.
- Método
- Una capacidad del Objeto, como caminar.
- Constructor
- Es un método llamado en el momento de la creación de instancias.
- Herencia
- Una Clase puede heredar características de otra Clase.
- Encapsulamiento
- Una Clase sólo define las características del Objeto, un Método sólo define cómo se ejecuta el Método.
- Abstracción
- La conjunción de herencia compleja, métodos, propiedades que un objeto debe ser capaz de simular en un modelo de la realidad.
- Polimorfismo
- Diferentes Clases podrían definir el mismo método o propiedad.
Recursos
- A Simple Explanation of OOP
- Chapter 3: What is Object-Oriented Programming?
- JavaScript OOP: A beginners guide
- Introducción a la POO en Javascript moderno: las nuevas clases en ES6
- MDN | Introducción a JavaScript orientado a objetos
- MDN | Object-oriented JavaScript for beginners
- Goodbye, Object Oriented Programming
- Why Object Oriented Programming is Awesome
- The Little Guide for OOP in JS
- Usando Clases en JavaScript
Entendiendo los objetos
/*
[Objeto]{
[ Propiedad = Variables (no funciónes) ]
[ Método = Solo funciónes ]
}
*/
Constructor de Objetos
var coche = function (parametros) {
/* Codigo*/
};
Propiedades del Objeto
var coche = function (marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad
this.color = color;
this.tipo = tipo;
};
Asignación en el Constructor
var coche = function (marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
this.detalles = function(){
console.log("Tu coche es un "+this.marca+" "+this.modelo+" con "+this.antiguedad+" años, clase "+this.tipo+" y color "+this.color);
}
};
var miCoche = new coche ("Seat", "Panda", 20, "azul", "turismo");
miCoche.detalles();
Extensión del prototipo
var coche = function (marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
};
coche.prototype.detalles = function(){
console.log("Tu coche es un "+this.marca+" "+this.modelo+" con "+this.antiguedad+" años, clase "+this.tipo+" y color "+this.color);
}
var miCoche = new coche ("Seat", "Panda", 20, "azul", "turismo");
miCoche.detalles();
Vinculación Externa
var coche = function (marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
this.detalles = dameDetalles;
};
function dameDetalles(){
console.log("Tu coche es un "+this.marca+" "+this.modelo+" con "+this.antiguedad+" años, clase "+this.tipo+" y color "+this.color);
}
var miCoche = new coche ("Seat", "Panda", 20, "azul", "turismo");
miCoche.detalles();
Herencia (simplificada)
var perro = function () {
this.patas = 4;
this.ojos = 2;
};
var pastorAleman = function () {
this.colorLengua = "negra";
this.colorOjos = "marrón";
this.capacidadTrabajo = true;
this.especialidad = "Pastoreo";
};
pastorAleman.prototype = new perro();
var miPerro = new pastorAleman();
console.log("Número patas: "+miPerro.patas+"\n Número ojos: "+miPerro.ojos+"\n Color Lengua: "+miPerro.colorLengua+"\n Color ojos: "+miPerro.colorOjos+"\n Capacidad de trabajo: "+miPerro.capacidadTrabajo+"\n Especialidad: "+miPerro.especialidad);
Herencia clásica
var coche = function (marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
this.detalles = dameDetalles;
};
var furgon = function (taraMinima, cargaUtil, volumenCarga) {
this.taraMinima = taraMinima;
this.cargaUtil = cargaUtil;
this.volumenCarga = volumenCarga;
this.detallesTecnicos = detallesTecnicos;
};
function dameDetalles(){
console.log("Tu coche es un "+this.marca+" "+this.modelo+" con "+this.antiguedad+" años, clase "+this.tipo+" y color "+this.color);
}
function detallesTecnicos(){
console.warn("Tu coche tiene una Tara mínima de "+this.taraMinima+". Carga útil de "+this.cargaUtil+" y un volumen de carga de "+this.volumenCarga+"m3");
}
var miPickup = new coche ("Land Rover", "Santana Aníbal", 35, "Marrón tierra", "4x4");
miPickup.prototype = new furgon (1200, 768, 4.5);
miPickup.detalles();
miPickup.prototype.detallesTecnicos();
Métodos y atributos privados y públicos
var cocheEmpresa = function (marca, modelo, antiguedad, color, tipo) {
// públicas
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
// privadas
var ITVPasada = true;
var ITVfrecuencia = "Cada año";
var seguroEnRegla = true;
var companySeguros = "SegurExpress";
var tipoSeguro = "a terceros";
// Público
this.dameDetalles = function () {
console.log("Tu coche es un "+marca+" "+modelo+" con "+antiguedad+" años, clase "+tipo+" y color "+color);
}
// Privadas
function datosPrivados() {
if (ITVPasada && seguroEnRegla)
console.info("INFO: Todo en Regla, tienes que pasar la ITV "+ITVfrecuencia+". Tienes un seguro "+tipoSeguro+" con "+companySeguros);
else{
console.error("ALERTA! El coche no puede usarse. El seguro o la ITV no esta en regla.");
}
}
datosPrivados();
this.dameDetalles();
};
var miCoche = new cocheEmpresa ("Audi", "S8", 2, "negro", "Berlina");
var miCoche2 = new cocheEmpresa ("Audi", "S4", 2, "Rojo", "Compacto");
Datos opcionales
var cocheEmpresa = function (marca, modelo, antiguedad, color) {
this.marca = marca || "Seat";
this.modelo = modelo || "Ibiza";
this.antiguedad = antiguedad || 6;
this.color = color || "Azul Corporativo";
this.dameDetalles = function () {
console.log("Tu coche es un "+this.marca+" "+this.modelo+" con "+this.antiguedad+" años y color "+this.color);
}
this.dameDetalles();
};
var miCoche = new cocheEmpresa ("Audi", "S8", 2, "negro", "Berlina");
var miCoche2 = new cocheEmpresa ();
var otroCoche = new cocheEmpresa ("Seat", "Leon");
Reutilizando el contexto común
// Creamos un ID
var contador = 0;
var cocheEmpresa = function (marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
this.id = contador++;
var ITVPasada = true;
var ITVfrecuencia = "Cada año";
var seguroEnRegla = true;
var companySeguros = "SegurExpress";
var tipoSeguro = "a terceros";
this.dameDetalles = function () {
console.log("Tu coche es un "+marca+" "+modelo+" con "+antiguedad+" años, clase "+tipo+" y color "+color);
}
function datosPrivados() {
if (ITVPasada && seguroEnRegla)
console.info("INFO: Todo en Regla, tienes que pasar la ITV "+ITVfrecuencia+". Tienes un seguro "+tipoSeguro+" con "+companySeguros);
else{
console.error("ALERTA! El coche no puede usarse. El seguro o la ITV no esta en regla.");
}
}
function identificador(){
console.warn("Recuerda! Tu coche esta identificado como coche numero "+contador);
}
datosPrivados();
this.dameDetalles();
identificador();
};
var miCoche = new cocheEmpresa ("Audi", "S8", 2, "negro", "Berlina");
var otroCoche = new cocheEmpresa ("Audi", "A8", 5, "gris", "Berlina");
var miCoche2 = new cocheEmpresa ("Seat", "Ibiza", 9, "rojo", "Utilitario");
console.info("Total de coches de empresa hasta el momento "+contador);
var coche = {
marca: "Seat",
modelo: "Panda",
antiguedad: 20,
color: "azul",
tipo: "turismo"
};
var clonCoche = Object.create(coche);
console.log(clonCoche.marca+" "+clonCoche.modelo);
Object.prototype.isPrototypeOf()
console.log(coche.isPrototypeOf(clonCoche));
function arbol (nombre) {
this.nombre = nombre;
}
var miArbol = new arbol( "Pino" );
console.log( "miArbol.constructor es " + miArbol.constructor );
function Perro(nombre, criadero, color, sexo) {
this.nombre=nombre;
this.criadero=criadero;
this.color=color;
this.sexo=sexo;
}
var elPerro = new Perro("Gabby","Laboratorio","chocolate","femenino");
elPerro.toString();
Perro.prototype.toString = function perroToString() {
var retorno = "Perro " + this.nombre + " es " + this.sexo + " " + this.color + " " + this.criadero;
return retorno;
};
elPerro.toString();
Definición de Clases
class coche{
constructor(marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
}
detalles() {
console.log(`Tu coche es un ${this.marca} ${this.modelo} con ${this.antiguedad} años, clase ${this.tipo} y color ${this.color}`);
}
}
let miCoche = new coche ("Seat", "Panda", 20, "azul", "turismo");
miCoche.detalles();
/* ECMA 5
var coche = function (marca, modelo, antiguedad, color, tipo) {
// Propiedades
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
// Metodos
this.detalles = function(){
console.log("Tu coche es un "+this.marca+" "+this.modelo+" con "+this.antiguedad+" años, clase "+this.tipo+" y color "+this.color);
}
};
var miCoche = new coche ("Seat", "Panda", 20, "azul", "turismo");
miCoche.detalles();
*/
Extensión de clases
class perro {
constructor(nombre) {
this.patas = 4;
this.ojos = 2;
this.nombre = nombre;
}
ladrar() {
console.log(`${this.nombre} esta ladrando!`);
};
}
class pastorAleman extends perro {
constructor(nombre) {
super('pastorAleman');
this.colorLengua = "negra";
this.colorOjos = "marrón";
this.capacidadTrabajo = true;
this.especialidad = "Pastoreo";
}
informacion() {
console.log(`Nombre: ${this.nombre}
Número patas: ${this.patas}
Número ojos: ${this.ojos}
Color ojos: ${this.colorOjos}
Color Lengua: ${this.colorLengua}
Capacidad de trabajo: ${this.capacidadTrabajo}
Especialidad: ${this.especialidad}`);
}
}
let miPerro = new pastorAleman('Golden');
miPerro.informacion();
miPerro.ladrar();
/* ECMA 5
var perro = function (nombre) {
this.patas = 4;
this.ojos = 2;
this.nombre = nombre;
this.ladrar = function(){
console.log(this.nombre + " esta ladrando!");
}
};
var pastorAleman = function () {
this.colorLengua = "negra";
this.colorOjos = "marrón";
this.capacidadTrabajo = true;
this.especialidad = "Pastoreo";
this.informacion = function(){
console.log("Nombre: "+this.nombre+"\nNúmero patas: "+this.patas+"\nNúmero ojos: "+this.ojos+"\nColor Lengua: "+this.colorLengua+"\nColor ojos: "+this.colorOjos+"\nCapacidad de trabajo: "+this.capacidadTrabajo+"\nEspecialidad: "+this.especialidad);
}
};
pastorAleman.prototype = new perro("Golden");
var miPerro = new pastorAleman();
miPerro.informacion();
miPerro.ladrar();
*/
Métodos Estáticos
class coche{
static info (edad){
console.info(`Tienes ${edad} años ${ edad >= 18 ? "y puedes conduccir": "y ... ¡Sorpresa! No puedes conduccir."}`);
}
constructor(marca, modelo, antiguedad, color, tipo) {
this.marca = marca;
this.modelo = modelo;
this.antiguedad = antiguedad;
this.color = color;
this.tipo = tipo;
}
detalles() {
console.log(`Tu coche es un ${this.marca} ${this.modelo} con ${this.antiguedad} años, clase ${this.tipo} y color ${this.color}`);
}
}
coche.info(50);
coche.info(8);
let miCoche = new coche ("Seat", "Panda", 20, "azul", "turismo");
miCoche.detalles();
Getters/Setters
class Rectangle {
constructor (width, height) {
this._width = width
this._height = height
}
set width (width) { this._width = width }
get width () { return this._width }
set height (height) { this._height = height }
get height () { return this._height }
get area () { return this._width * this._height }
}
var r = new Rectangle(50, 20)
r.area === 1000
/* ECMA5
var Rectangle = function (width, height) {
this._width = width;
this._height = height;
};
Rectangle.prototype = {
set width (width) { this._width = width; },
get width () { return this._width; },
set height (height) { this._height = height; },
get height () { return this._height; },
get area () { return this._width * this._height; }
};
var r = new Rectangle(50, 20);
r.area === 1000;
*/
Getters/Setters con arrays tipados
// ES6 class equivalent to the following C structure:
// struct Example { unsigned long id; char username[16]; float amountDue }
class Example {
constructor (buffer = new ArrayBuffer(24)) {
this.buffer = buffer
}
set buffer (buffer) {
this._buffer = buffer
this._id = new Uint32Array (this._buffer, 0, 1)
this._username = new Uint8Array (this._buffer, 4, 16)
this._amountDue = new Float32Array(this._buffer, 20, 1)
}
get buffer () { return this._buffer }
set id (v) { this._id[0] = v }
get id () { return this._id[0] }
set username (v) { this._username[0] = v }
get username () { return this._username[0] }
set amountDue (v) { this._amountDue[0] = v }
get amountDue () { return this._amountDue[0] }
}
let example = new Example()
example.id = 7
example.username = "John Doe"
example.amountDue = 42.0
Usando Weakmap
class ClearableWeakMap {
constructor(init) {
this._wm = new WeakMap(init)
}
clear() {
this._wm = new WeakMap
}
delete(k) {
return this._wm.delete(k)
}
get(k) {
return this._wm.get(k)
}
has(k) {
return this._wm.has(k)
}
set(k, v) {
this._wm.set(k, v)
return this
}
}
- Crear la clase Persona propiedades nombre, edad y género, y el método obtDetalles(), que muestra por pantalla las propiedades de la persona.
- Crear la clase Estudiante, que hereda de Persona, e incluye las propiedades curso y grupo y el método registrar(), que muestre por pantalla el resultado.
- Crear la clase Profesor, que hereda de Persona, e incluye las propiedades asignatura y nivel y el método asignar(), que muestre por pantalla el resultado.
- Crear los objetos y casos de prueba necesarios para comprobar el correcto funcionamiento de la jerarquía de clases.
//Tu solución