Skip to content

Latest commit

 

History

History
564 lines (437 loc) · 14.3 KB

File metadata and controls

564 lines (437 loc) · 14.3 KB

shieldsIO shieldsIO shieldsIO

WideImg

Master en Programación de Aplicaciones con JavaScript y Node.js

JS, Node.js, Frontend, Express, Patrones, IoT, HTML5_APIs, Asincronía, Websockets, ECMA6, ECMA7

Clase 32

POO

  • 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;
	};

Métodos

  • 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

  • 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);

POO en detalle

  • 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");

POO Avanzado

  • 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);

Trabajando con prototipos

  • .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();