- Programación basada en prototipos
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.
- 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;
};
- 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:
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();
- 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);
- Privado y público:
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");
- Creando 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);
- Extensión de objetos nativos (usando prototipos):
Array.prototype.coincidencias = function(palabra) {
var coincidencias = 0;
for (var i=0; i<this.length; i++) {
if (this[i] == palabra) {
coincidencias++;
}
}
console.warn("Se encontraron "+coincidencias+" coincidencia(s) de la palabra");
};
var amigos = ["Charlie", "Marco", "Luis", "Jose", "Miguel", "Jose", "Luis", "Oscar"];
amigos.coincidencias("Jose");
-
Dominando los Contextos de this:
- Window:
console.log( this === window ); function prueba(){ console.log( this === window); } prueba();
- Otro Contexto:
var usuario = { nombre : 'Yo', apellido : 'Mismo', nombreCompleto : this.nombre + this.apellido, metodoNombre: function(){ return this.nombre + " " + this.apellido }, valorThis: function (){ console.log(this); } } // ERROR - Undefined -> this=window console.log("usuario.nombreCompleto", usuario.nombreCompleto); // FUNCIONA - this=usuario console.log("usuario.metodoNombre()", usuario.metodoNombre()); // FUNCIONA - this=usuario usuario.valorThis();
-
Usando this:
var objeto = { valor: 0, incrementar: function(incremento){ this.valor += incremento; } }; objeto.incrementar(6); console.log("objeto.valor:", objeto.valor)
-
Alternado el valor de this:
- ERROR!:
var objeto = { valor: 0, incrementar: function(incremento){ function otraFuncion(unValor){ this.valor += unValor; } otraFuncion(incremento); } }; objeto.incrementar(6); // objeto.valor
- CORRECTO:
var objeto = { valor: 0, incrementar: function(incremento){ var esto = this; function otraFuncion(unValor){ esto.valor += unValor; } otraFuncion(incremento); } }; objeto.incrementar(6); // objeto.valor
-
Usando this en Constructor:
var fabricaPersonas = function(){ this.nombre = 'Pepe'; }; fabricaPersonas.prototype.mostrarNombre = function(){ console.log(this.nombre); }; var miPersona = new fabricaPersonas(); miPersona.mostrarNombre();
-
Usando .apply() para modificar el contexto del this:
var fabricaPersonas = function(){ this.nombre = 'Pepe'; }; fabricaPersonas.prototype.mostrarNombre = function(){ console.log(this.nombre); }; var otroObjeto = { nombre: 'Oscar' }; var miPersona = new fabricaPersonas(); miPersona.mostrarNombre(); miPersona.mostrarNombre.apply(otroObjeto);
-
Modificación de contexto
-
con .call():
var objeto = { multiplicador: 2, sumatorio: function(num1, num2){ return (num1 + num2) * this.multiplicador; } }; var resultado = objeto.sumatorio(2,2); console.log(resultado); var cambio = { multiplicador: 5 }; var resultado = objeto.sumatorio.call(cambio, 5, 5); console.log(resultado);
-
con .apply():
var objeto = { multiplicador: 2, sumatorio: function(num1, num2){ return (num1 + num2) * this.multiplicador; } }; var resultado = objeto.sumatorio(2,2); console.log(resultado); var cambio = { multiplicador: 5 }; var resultado = objeto.sumatorio.apply(cambio, [5,5]); console.log(resultado);
-
con .bind():
var objeto = { multiplicador: 2, sumatorio: function(num1, num2){ return (num1 + num2) * this.multiplicador; } }; var resultado = objeto.sumatorio(2,2); console.log(resultado); var cambio = { multiplicador: 5 }; var cambiandoFuncion = objeto.sumatorio.bind(cambio); var resultado = cambiandoFuncion(5, 5); console.log(resultado);
-
-
.create():
var coche = { marca: "Seat", modelo: "Panda", antiguedad: 20, color: "azul", tipo: "turismo" }; var clonCoche = Object.create(coche); console.log(clonCoche.marca+" "+clonCoche.modelo);
-
.isPrototypeOf():
console.log(coche.isPrototypeOf(clonCoche));
-
.constructor():
function arbol (nombre) { this.nombre = nombre; } var miArbol = new arbol( "Pino" ); console.log( "miArbol.constructor es " + miArbol.constructor );
-
.toString():
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();