Skip to content

Latest commit

 

History

History
2557 lines (2042 loc) · 65.4 KB

File metadata and controls

2557 lines (2042 loc) · 65.4 KB

Clase 2 - Reintroducción a JS

Un poco de humor

chiste

Cortesía de CommitStrip

JSHint

Modo Estricto

El modo estricto hace varios cambios en la semántica normal de JavaScript. Primero, modo estricto elimina algunos errores silenciosos de JavaScript cambiando a que lance los errores. Segundo, modo estricto corrige errores que hacen que sea difícil para los motores de JavaScript para realizar optimizaciones: código de modo estricto a veces se puede hacer para correr más rápido que el código idéntico que no es estricto. Tercero, el modo estricto prohíbe sintaxis que es probable que sea definida en futuras versiones de ECMAScript.

En resumen:

  • Detectaremos más errores
  • Mejora la interpretación, lo que aumenta la velocidad de ejecucción.
  • Previene que usemos sintaxis de futuras versiones de ECMAScript.

Aplicándolo a todo nuestro código

// ./script.js
(function() {
  "use strict";

  // Nuestro código

})();

Aplicándolo solo en parte del código

// ./script.js
function estricta(){
  'use strict';
  function anidada() {
      return "Yo también!";
  }
  return "Hola! Soy una función en modo estricto!  " + anidada();
}

function noEstricta() {
    return "yo no soy una función estricta.";
}

Algunos ejemplos:

  • Error: Usar variables u objetos sin declararlos antes.
    function estricto(){
        'use strict';
        pi = 3.14;
        console.log(pi);
    }
  • Error: Borrar variables, objetos o funciones.
    function estricto(){
        'use strict';
        pi = 3.14;
        delete pi
    }
  • Error: Duplicar parámetros
    function estricto(){
        'use strict';
        function x (p1, p1){
            // código
        }
    }
  • Error: Al usar carácteres escapados
    function estricto(){
        'use strict';
        var x = \010; 
    }

Error: Al usar writable:false

    function estricto(){
        'use strict';
        var obj = {};
        Object.defineProperty(obj, "x", {value:0, writable:false});
        obj.x = 3.14;
    }

Error: Al usar with

    function estricto(){
        'use strict';
        with (Math){x = cos(2)};
    }

Error: Al usar eval() por seguridad

    function estricto(){
        'use strict';
        eval ("var x = 2");
        console.log(x);
    }

Otras palabras reservadas en modo estricto:

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield

Variables

  • No se pueden usar espacios
var con espacios = 1;
  • No usar un número delante
var 1numero = 1;
  • Válidos, pero no recomendado
var con_guiones_bajos = 1;
var dame$ = 1;
var otraOpcion = 1;
var opcionCon123123 = 1;

Tipos de variables

Operador typeof y su especificación

  • Undefined
typeof undefined
typeof noDefinido
typeof tampocoCreado
  • Object
typeof null
typeof [15, 4]
typeof new Date()
typeof {a:1}
  • Boolean
typeof false
typeof true
typeof Boolean(false)
  • Number
typeof 3
typeof 3.14
typeof NaN
typeof Infinity
  • String
typeof "hola"
  • Function
typeof function(){}
typeof class C {}
  • Symbol (ECMA6)

Ahora tenemos los símbolos, nuevo tipo de datos que sirve como identificador único para atributos de objetos EcmaScript 6: Símbolos de Miguel Sánchez

typeof Symbol()
typeof Symbol('simbolo')

Caracteres especiales:

    /*
    \t -> Tabulador
    \' -> Comillas Simples
    \" -> Comillas Dobles
    \\ -> \
    \n -> Salto de línea
    */

    function caracteresDemo () {
    console.log("Hasta aquí... todo correcto. Ahora vamos a \"tabular\":\tves? Ya estamos más lejos.\n\'Otra linea ;-)\'")
    };

Comentarios

  • Una línea
// Comentario en una línea
  • Multiples Líneas
/*
Una Línea....
Otra linea...
Etc...
*/

Matemáticas Básicas

var suma = 5 + 4;
var resta = 10 - 6;
var multiplicacion = 3 * 3;
var division = 6 / 2;
var modulo = 43 % 10;

function calcular (operacion) {
    console.log(operacion);
};

Matemáticas Básicas: Agrupando operaciones

var expresion1 = (3 + 7) * 10;
var expresion2 = (-56 * 6) - 74 * -25;
var expresion3 = (3 * 3) + 10 - 12 / 2;
var expresion4 = 44 + (83 % (33 + 100));
var expresion5 = -145 + (500 / 10 - 5) + 10 * 10 ;

function calcular (operacion) {
    console.log(operacion);
};

Matemáticas Básicas: crecimiento y decrecimiento

var numero = 5;

console.log(--numero); // 4
console.log(numero--); // 5 (luego 4)
console.log(++numero); // 6
console.log(numero++); // 5 (luego 6)

Operadores de asignación

  • = Asignacion
var x = 1;
var y = 2;
x = y;
console.info("\"x\" vale ", x);
  • += Suma
var x = 1;
var y = 2;
x += y;
console.info("\"x\" vale ", x); // x = x + y
  • -= Resta
var x = 1;
var y = 2;
x -= y;
console.info("\"x\" vale ", x); // x = x - y
  • *= Multiplicación
var x = 1;
var y = 2;
x *= y;
console.info("\"x\" vale ", x); // x = x * y
  • /= División
var x = 1;
var y = 2;
x /= y;
console.info("\"x\" vale ", x); // x = x / y
  • %= Resto
var x = 1;
var y = 2;
x %= y;
console.info("\"x\" vale ", x); // x = x % y

Comparadores básicos

var mayorQue = 100 > 10;
var menorQue = 10 < 100;
var mayorIgual = 100 >= 10;
var menorIgual = 10 <= 100;
var igual = 10 == 10;
var igualTotalmente = 10 === 10;
var noIgual = 100 != 10;

function comparar (dato) {
    console.log(dato);
};

Comparadores complejos

  • AND(&&)
    var comparacion;
    comparacion = true && true; // true
    comparacion = true && false // false
    comparacion = false && false // false
    comparacion = false && true // false
  • OR(||)
    var comparacion;
    comparacion = true || true; // true
    comparacion = true || false // true
    comparacion = false || false // false
    comparacion = false || true // true
  • Ejemplos:
var ex1 = true && true; // true
var ex2 = (2 == 2) && (3 >= 6); // false
var ex3 = (2>3) || (17 <= 40); // true
var ex4 = false || false; // false

function condicionalAvanzado ( paraComparar ) {
    if (paraComparar) {
        console.log("Verdadero!");
    } else {
        console.log("falso!");
    };
};

Otros datos

  • Valor real es true:
console.log("valor boleano de \"Fictizia\":", Boolean("Fictizia")  );
console.log("valor boleano de 1235:", Boolean(1235));
console.log("valor boleano de -1235:", Boolean(-1235));
console.log("valor boleano de un objeto:", Boolean({saludo: "hola"}));
console.log("valor boleano de un array:", Boolean(["platano", -1, false]));
console.log("valor boleano de un array:", Boolean(function(){}));
  • Sin valor real es false:
console.log("valor boleano de \"\":", Boolean("")  );
console.log("valor boleano de 0:", Boolean(0));
console.log("valor boleano de -0:", Boolean(-0));
console.log("valor boleano de null:", Boolean(null));
console.log("valor boleano de undefined:", Boolean(undefined));
console.log("valor boleano de NaN:", Boolean(NaN));

Asignación por igualdad

	var administrador = 'Yo mismo';
	var esAdministrador = (administrador === 'Yo mismo');

If... else

  • Estructura:

    /* IF ...ELSE
    if (-algo verdadero-) {
        -ejecutaremos este código-
    } else {
        -Si lo anterior no era verdadero, se ejecutara este código-
    };
    */
  • Documentación:

  • Ejemplo:

    if (true) {
        console.log("true, por eso me ejecuto");
    } else {
        console.log("false, por eso me ejecuto");
    }

Else if...

function testCondiccion (condicion){
    if (condicion == 1) {
        console.log("1, por eso me ejecuto");
    } else if (condicion == 2){
        console.log("2, por eso me ejecuto");
    } else {
        console.log("no es 1 o 2, por eso me ejecuto");
    }
}

Switch

  • Estructura:

    /* Switch
    switch(expresión) {
        case n:
            //Código
            break;
        case n:
            //Código
            break;
        default:
            //Código
    }
    */
  • Documentación:

  • Casos únicos:

    var nombre = "";
    switch (nombre) {
      case "Pepe":
        console.log("Hola Pepe");
        break;
      case "Luis":
        console.log("Hola Luis");
        break;
      case "Antonio":
        console.log("Hola Antonio");
        break;
      default:
        console.log('Ninguno de los nombres que pensamos... es '+nombre);
    }
  • Multiples coincidencias:

    var nombre = "";
    switch (nombre)
    {
       case "Pepe":
       case "Luis":
       case "Antonio":
           alert('Hola '+nombre);
           break;
    
       default:
           console.log('Ninguno de los nombres que pensamos... es '+nombre);
    }

Operador Ternario (?:)

  • Estructura:

    /* 
    -- Una operación por caso --
    condicion ? expresion1 : expresion2 
    
    -- Multiples Operaciones por caso --
    condicion ? (
    	operacion1,
    	operacion2,
    	otraoperacion
    ) : ( 
    	operacion1,
    	operacion2,
    	otraoperacion
    );
    
    -- Evaluaciones multiples --
    	condicion ? expresion1 : condicion2 ? expresion1 : expresion2;
    */
  • Una operación por caso:

	var esMiembro = true;
	console.info("El pago son  " + (esMiembro ? "20.00€" : "50.00€"));
  • Evalución múltiple:
	var esMiembro = true;
	var esAdulto = true;
	console.info(esMiembro ? "El pago son 20.00€" : esAdulto ? "Puedes enviar la solicitud cuando quieras" : "Tines que esperar aún. Lo siento.");
  • Múltiples Operaciones:
	var mensaje,
	esMiembro = true;
	
	esMiembro ? (
		mensaje = "El pago son 20.00€",
		console.info(mensaje)
	) : (
		mensaje = "El pago son 50.00€",
		console.info(mensaje)
	);

While

  • Estructura:

    /*  --while--
    while (-Condición-) {
        -Instrucciones-
    };
    */
  • Documentación:

  • Bucle infinito: Este es un error muy común.

    while (true) {
        console.log("Este texto se imprime hasta el infinito...");
    };
  • Bucle que no se ejecutará:

    while (false) {
        console.log("Este texto jamas se imprimirá...");
    };
  • Ejemplo:

    var control = 1;
    while (control <= 10) {
        console.log(control);
        control++;
    };

For

  • Estructura:

    /*  --for--
    for (-Expresión inicial-; -Condición-; -Expresión Actualización-) {
        -Instrucciones-
    };
    */
  • Documentación:

  • Ejemplo clásico:

    for (var i = 0; i < 10; i++) {
        console.log(i);
    }

Do... While

  • Estructura:

    /* --Do...while--
    do{
       -Instrucciones-
    } while (-Condición-);
    */
  • Documentación:

  • Ejemplo:

    var i = 0;
    do {
       i++;
       console.log(i);
    } while (i < 10);
  • Al menos se ejecutará una vez, aunque la premisa no sea verdadera.

    do{
       console.warn("me ejecuto")
    } while (false);

Break y Continue

  • Continue nos permite saltar parte del bucle.
for (var i = 0; i < 10; i++) {
    
    // Salta el 5 y sigue...
    if (i === 5) { 
    	continue; 
    }
    
    console.log("El valor de i es "+i);
}
  • Break nos permite salir del bucle.
for (var i = 0; i < 10; i++) {
    
    // Llega a 5 y sale.
    if (i === 5) { 
    	break; 
    }
    
    console.log("El valor de i es "+i);
}

Usos Avanzados

  • Ejemplo usando decrecimiento:

    for (var i = 10; i > 0; i--) {
        console.log(i);
    }    
  • Ejemplo usando varios contadores:

    for (var i = 0, x = 1, z = 2, tope = 10; i <= tope; x *= z, i++ ) {
        console.log("i vale "+i+", x vale "+x+", z vale "+z);
    }

Números

Propiedades

  • Notación científica

  • .MAX_VALUE() El número más grande representable (1.7976931348623157e+308):

       var numero1 = 1.7976931348623157e+308;
       var numero2 = 1.7976931348623157e+310;
       
       function verificarValorMaximo(num){
       
       	if (num <= Number.MAX_VALUE) {
       	  console.log("El número no es infinito");
       	} else {
       	  console.log("El número es infinito");
       	}
       	
       }
       
       verificarValorMaximo(numero1);
       verificarValorMaximo(numero2);    
  • .MIN_VALUE() El número más pequeño representable (5e-324):

       var numero1 = 5e-323;
       var numero2 = 5e-326;
       
       function verificarValorMinimo(num){
       
       	if (num >= Number.MIN_VALUE) {
       	  console.log("El número no es infinito");
       	} else {
       	  console.log("El número es infinito");
       	}
       	
       }
       
       verificarValorMinimo(numero1);
       verificarValorMinimo(numero2);
  • .NEGATIVE_INFINITY() El valor negativo de la propiedad del objeto global Infinity:

        var numeroMinimo = (-Number.MAX_VALUE) * 2
        console.log(numeroMinimo);
        
        if (numeroMinimo === Number.NEGATIVE_INFINITY) {
         numeroMinimo = 0;
        }
        console.log(numeroMinimo);
  • .NaN() Not A Number:

        NaN === NaN;        // false
        Number.NaN === NaN; // false
        isNaN(NaN);         // true
        isNaN(Number.NaN);  // true    
  • .POSITIVE_INFINITY() Representa el infinito positivo:

        var numeroMaximo = Number.MAX_VALUE * 2
        console.log(numeroMaximo);
        
        if (numeroMaximo === Number.POSITIVE_INFINITY) {
         numeroMaximo = 0;
        }
        console.log(numeroMaximo);    

Métodos:

  • .toExponential() Devuelve una cadena con el valor número en formato de potencia:

        var numObj = 77.1234;
        
        console.log(numObj.toExponential());  // 7.71234e+1
        console.log(numObj.toExponential(4)); // 7.7123e+1
        console.log(numObj.toExponential(2)); // 7.71e+1
        console.log(77.1234.toExponential()); // 7.71234e+1   
  • .toFixed() Devulve un numero con decimales:

        var numObj = 12345.6789;
        
        numObj.toFixed();       //'12346' redondeo
        numObj.toFixed(1);      //'12345.7'
        numObj.toFixed(6);      //'12345.678900' Se añaden ceros en caso necesario
        (1.23e+20).toFixed(2);  //'123000000000000000000.00'
        (0).toFixed(2);         //'0.00'
        2.34.toFixed(1);        //'2.3' redondeo
        -2.34.toFixed(1);       //-2.3 Numeros negativos no son devueltos como cadenas.
        (-2.34).toFixed(1);     //'-2.3' En caso de usar paréntesis se salta la limitación 
  • .toLocaleString() Devulve una cadena con el valor numeral representado en lenguaje local:

        var numero = 3500;
        // En Local
        console.log(numero.toLocaleString()); // 3.500
        // En Árabe
        console.log(numero.toLocaleString('ar-EG')); // ٣٬٥٠٠
        // En Chino decimal
        console.log(numero.toLocaleString('zh-Hans-CN-u-nu-hanidec')); // 三,五〇〇
  • .toPrecision() Devuelve un numero precisado:

        var numero = 5.123456;
        
        console.log(numero.toPrecision());    // 5.123456
        console.log(numero.toPrecision(5));   // 5.1235
        console.log(numero.toPrecision(2));   // 5.1
        console.log(numero.toPrecision(1));   // 5
        console.log((1234.5).toPrecision(2)); // 1.2e+3 (En ocasiones )
  • .toString() Devuelve una cadena con el número en la base que determinemos:

        console.log((17).toString());     // '17'
        console.log((17.2).toString());   // '17.2'
        console.log((-0xff).toString(2)); // '-11111111'
        console.log((254).toString(16));  // 'fe'
  • .parseFloat() Devuelve un número décimal partiendo de una cadena:

        Number.parseFloat("3.14"); // 3.14
        Number.parseFloat("314e-2"); // 3.14
        Number.parseFloat("0.0314E+2"); // 3.14
        Number.parseFloat("3.14textos..."); // 3.14
        Number.parseFloat("1textos..."); //1
  • .parseInt() Devuelve un número entero en una base especifica o en base 10 partiendo de una cadena:

        parseInt(" 0xF", 16); // 15
        parseInt(" F", 16);  // 15
        parseInt("17", 8);  // 15
        parseInt(021, 8);  // 15
        parseInt("015", 10);  // 15
        parseInt(15.99, 10);  // 15
        parseInt("15,123", 10);  // 15
        parseInt("FXX123", 16);  // 15
        parseInt("1111", 2);  // 15
        parseInt("15*3", 10);  // 15
        parseInt("15e2", 10);  // 15
        parseInt("15px", 10);  // 15
        parseInt("12", 13);  // 15
  • Comparativas de rendimeinto interesantes

Math

Métodos:

  • .random() Devuelve un número aleatorio

        // Número aleatorio entre 0 (incluido) y 1 (excluido)
        Math.random(); 
        
        // Retorna un número aleatorio entre min (incluido) y max (excluido)
        Math.random() * (max - min) + min;
        Math.random() * (11 - 0) + 0;
        
        // Retorna un entero aleatorio entre min (incluido) y max (excluido)
        Math.floor(Math.random() * (11 - 0)) + 0;
  • .round() Devuelve el valor de un número redondeado al entero más cercano

        Math.round(20.5); // 21
        Math.round(20.49); // 20
        Math.round(-20.51); // -21
  • .Floor() Devuelve el máximo entero menor o igual a un número.

        Math.floor(20.5); // 21
        Math.floor(20.49); // 20
        Math.floor(-20.51); // -21
  • .max() retorna el mayor de cero o más números

        function calcularMayor(valor1, valor2, valor3){
            return Math.max(valor1, valor2, valor3);
        }
        
        // Mejorando calcularMayor
        function calcularMayor(){
        	var args = Array.prototype.slice.call(arguments);
        	return Math.max.apply(null, args);
        }
  • .min() retorna el menor de cero o más números

        function calcularExtremos(){
        	var args = Array.prototype.slice.call(arguments);
        	return {minimo: Math.min.apply(null, args),
        			maximo: Math.max.apply(null, args)
        	};
        }
        
        
        misExtremos = calcularExtremos(1,2,4,56,-123);
        
        console.log("Mínimo: "+misExtremos.minimo+"\n"+"Máximo: "+misExtremos.maximo);

Librerías:

Dates

Librerías:

Metodos

  • Creando Fechas:

    • Fecha Actual:
        var ahora = new Date();
        console.log(ahora);
    • Usando milisegundos (desde el 1/1/1970 00:00):
        var diaDespues = new Date(3600*24*1000);
        console.log(diaDespues);
    • Usando cadenas de texto:
        var newYear = new Date("January 1, 2016 00:00:00");
    • Usando números:
        var newYear = new Date(2016, 1, 1); // AAAA, MM, DD
        var newYear = new Date(2016, 1, 1, 0, 0, 0); // AAAA, MM, DD, HH, MM, SS
    • Usando UTC:
        var newYear = new Date(Date.UTC(2016, 1, 1));
  • Getters:

    • Local
        var ahora = new Date();
        console.log("La fecha es " + ahora);
        console.log("==== FECHA ====");
        console.log("El año: " + ahora.getFullYear()); // 4 digitos
        console.log("El mes: " + ahora.getMonth()); // 0 - 11
        console.log("El día de la semana: " + ahora.getDay()); // 0 - 6 (D - S)
        console.log("El día del mes: " + ahora.getDate()); // 1-31
        console.log("==== HORA ====");
        console.log("Horas: " + ahora.getHours());
        console.log("Minutos: " + ahora.getMinutes());
        console.log("Segundos: " + ahora.getSeconds());
        console.log("Milisegundos desde 1/1/1970: "+ ahora.getTime());
        console.log("milisegundos: " + ahora.getMilliseconds());
    • UTC
        var ahora = new Date();
        console.log("Con UTC: ";
        console.log("==== FECHA ====");
        console.log("El año: " + ahora.getUTCFullYear()); // 4 digitos
        console.log("El mes: " + ahora.getUTCMonth()); // 0 - 11
        console.log("El día de la semana: " + ahora.getUTCDay()); // 0 - 6 (D - S)
        console.log("El día del mes: " + ahora.getUTCDate()); // 1-31
        console.log("==== HORA ====");
        console.log("Horas: " + ahora.getUTCHours());
        console.log("Minutos: " + ahora.getUTCMinutes());
        console.log("Segundos: " + ahora.getUTCSeconds());
        console.log("milisegundos: " + ahora.getUTCMilliseconds());
  • Setters:

    • Local
        var newYear = new Date(Date.UTC(2016, 1, 1));
        console.info("La fecha es " + newYear);
        
        newYear.setFullYear(1980); // Pasamos a 1980
        console.info("La fecha es " + newYear);
        
        newYear.setDate(56); // 1 Enero + 56 Días
        console.info("La fecha es " + newYear);
        
        newYear.setUTCMilliseconds(1500); // 1500ms en formato UTC
        console.info("La fecha es " + newYear);
        
        newYear.setUTCHours(36); // le sumamos 36 horas
        console.info("La fecha es " + newYear);
        
        newYear.setMonth(-6); // le quitamos 6 meses
        console.info("La fecha es " + newYear);
  • Otros:

    • .getTimezoneOffset() Devuelve la diferencia entre tu zona horaria y UTC (en minutos)
        ahora.getTimezoneOffset();
    • .toString(), .toDateString(), .toTimeString() Devuelve una cadena con la fecha
        ahora.toString(); // Fecha y Hora
        ahora.toDateString(); // Solo Fecha
        ahora.toTimeString(); // Solo Hora
    • .toUTCString(), .toISOString() Devuelve una cadena con la fecha en formatos específicos
        ahora.toISOString(); // UTC
        ahora.toUTCString(); // ISO
    • .toLocaleString() Devuelve una cadena con la fecha en version local.
        
        var ahora = new Date();
        console.info(ahora.toLocaleString());
        
        // Código de idioma IETF para Alemán
        console.info(ahora.toLocaleString("de-DE"));
        
        // Opciones Avanzadas para fechas
        var opciones = { 
        weekday: 'long',
        year: 'numeric', 
        month: 'long', 
        day: 'numeric'};
        console.log(ahora.toLocaleString("de-DE", opciones));
    • .getTimezoneOffset() Devuelve la diferencia entre tu zona horaria y UTC (en minutos)
        ahora.getTimezoneOffset();
    • Tiempo transcurrido:
        var inicio = new Date();
        // + código
        var fin = new Date();
        var transcurso = fin.getTime() - inicio.getTime();
        console.info("Pasaron "+transcurso+"ms");

Truco

Usar getters para modificar fechas (días, meses, etc...) Nota: Partiendo del ejemplo de MDN

  • sin getters
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.toLocaleString(); // 6/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(24);
	theBigDay.toLocaleString() // 23/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(32);
	theBigDay.toLocaleString() // 31/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(22);
	theBigDay.toLocaleString() // 21/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(22 + 32 +24);
	theBigDay.toLocaleString() // 15/9/1962 23:00:00
  • con getters
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.toLocaleString(); // 6/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(theBigDay.getDate() + 24);  
	theBigDay.toLocaleString(); // 30/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(theBigDay.getDate() + 32);
	theBigDay.toLocaleString(); // 7/8/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(theBigDay.getDate() + 22);
	theBigDay.toLocaleString(); // 28/7/1962 23:00:00
	
	var theBigDay = new Date(1962, 6, 7);
	theBigDay.setDate(theBigDay.getDate() + 22 + 32 + 24);
	theBigDay.toLocaleString(); // 22/9/1962 23:00:00

String

Propiedades:

  • .length() Devuelve la longitud:
var cadena = "Fictizia";

console.log("Fictizia tiene " + cadena.length + " caracteres.");

console.log("Una cadena vacia tiene " + ''.length + " caracteres.");

Métodos:

  • .fromCharCode() Devuelve una cadena creada mediante una secuencia Unicode:
	console.info("Es es el año 2016 ("+ String.fromCharCode(8559,8559,8553,8548,8544) + ")");
  • .anchor() Crea un ancla HTML:
	document.body.innerHTML = "Contenidos".anchor("contenidos"); 
	// "<a name="contenidos">Contenidos</a>"
  • .charAt() Devuelve el carácter específico:
var cadena="Fictizia";
console.log("El carácter(posición) 3 es '" + cadena.charAt(3) + "'")
  • .charCodeAt() Devuelve el valor Unicode:
var cadena="Fictizia";
console.log("El carácter(posición) 3 es '" + cadena.charAt(3) + "', en unicode ("+cadena.charCodeAt(3)+")")
  • .concat() Combina el texto de dos o más cadenas:
var cadena1 = "Oh ";
var cadena2 = "qué maravillosa ";
var cadena3 = "mañana'.";
var combinacion = cadena1.concat(cadena2,cadena3);
console.log(combinacion); // devuelve "Oh qué maravillosa mañana'."
  • .indexOf() Devuelve el índice o -1:
"Mundo Web".indexOf("Web") // 6
"Mundo Web".indexOf("web") // -1
  • .lastIndexOf() Devuelve el índice de la última coincidencia o -1:
"Fictizia".lastIndexOf("i"); // 6
"Fictizia".lastIndexOf("f"); // -1
  • .link() Crea un enlace:
var textoActivo="Nuestro Curso"
var url="http://www.fictizia.com/formacion/curso_node"
document.body.innerHTML = "Haga click para volver a " + textoActivo.link(url);
  • .slice() Devuelve una cadena nueva con una sección de otra:
var cadena = "Fictizia";
console.log(cadena.slice(5)); // zia
console.log(cadena.slice(0, 5)); // Ficti
console.log(cadena.slice(3, -1)); // tizi
  • .split() Divide una cadena usando un separador:
function dividirCadena(cadenaADividir,separador) {
   var arregloDeCadenas = cadenaADividir.split(separador);
   console.log('<p>La cadena original es: "' + cadenaADividir + '"');
   console.warn('<br>El separador es: "' + separador + '"');
   console.log("<br>El arreglo tiene " + arregloDeCadenas.length + " elementos: ");

   var elementos = "";
   for (var i=0; i < arregloDeCadenas.length; i++) {
      elementos += arregloDeCadenas[i] + " / ";
   }

   console.info(elementos);

}

var cadenaVerso = "Lorem Ipsum es simplemente el texto de relleno de las imprentas y archivos de texto. Lorem Ipsum ha sido el texto de relleno estándar de las industrias desde el año 1500";
var cadenaMeses = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec";

var espacio = " ";
var coma = ",";

dividirCadena(cadenaVerso, espacio);
dividirCadena(cadenaVerso);
dividirCadena(cadenaMeses, coma);
  • .substr() Devuelve los caracteres de una cadena comenzando en la localización especificada, y en el número de caracteres especificado.:
var cadena = "Fictizia";
console.log("(0,5): "    + cadena.substr(0,5)); // Ficti
console.log("(5,3): "    + cadena.substr(5,3)); // zia
  • .substring() Devuelve un subconjunto:
var cadena = "Fictizia";
console.log("(0,5): "    + cadena.substring(0,5)); // Ficti
  • .toLocaleLowerCase() Devuelve todo en minúsculas con las características locales:
console.log('FICTIZIA'.toLocaleLowerCase()); // 'fictizia'
  • .toLocaleUpperCase(Devuelve todo en mayúsculascon las características locales) **:
console.log('fictizia'.toLocaleUpperCase()); // 'FICTIZIA'
  • .toLowerCase() Devuelve todo en minúsculas:
console.log('FICTIZIA'.toLowerCase()); // 'fictizia'
  • .toUpperCase() Devuelve todo en mayúsculas:
console.log('fictizia'.toUpperCase()); // 'FICTIZIA'
  • .trim() Elimina espacios vacios al principio y final de la cadena:
console.log('  Fictizia '.trim()); // 'Fictizia'

Arrays

  • Creando un array:

    var arreglo = [];
    arreglo = [1, "platano", "piscina", "manzana", true];
  • Usando el Índice:

    arreglo[1];
  • Cambiar un valor del Índice:

    arreglo[0] = "fresa";
    arreglo[4] = "pera";
    arreglo[2] = "limón";
  • delete sobrescribe a undefined

    delete arreglo[0];
  • Elementos vacios:

    arreglo[0] = undefined;

Propiedades

  • Índice total:

    	arreglo.length;
  • Usando el Índice total en un bucle:

    var numeros = [1, 2, 3, 4, 5];
    for (var i = 0; i < numeros.length; i++) {
      numeros[i] *= 10;
    }

Métodos

  • .push() Añadir elemento al índice:

    arreglo.push("nuevo");
  • .pop() Eliminar el último elemento del índice:

    	arreglo.pop();
  • .shift() Eliminar el primer elemento:

    	arreglo.shift();
  • .splice() Borrar:

    	var manzana = arreglo.splice(3, 1);
  • .map():

    var arreglo = ["plátano", "fresa", "lima", "manzana"];
    var resultado = arreglo.map(function (elemento){return elemento + " modificado!"});
    console.log(resultado);
  • .isArray():

    	var arreglo = [1,2,3]
    	
    	// true
    	Array.isArray([1]);
    	Array.isArray(arreglo);
    	
    	// false
    	Array.isArray();
    Array.isArray({});
    Array.isArray(null);
    Array.isArray(undefined);
  • .concat() Retorna un nuevo Array con los Arrays especificados concatenados:

    • Dos Arrays:
    	var arreglo = ['a', 2, true];
    	var arreglo2 = [1, 2, 4];
    
    	var nuevaArray = arreglo.concat(arreglo2);
    
    console.log(nuevaArray); 
    • Múltiples Arrays:
    	var arreglo = ['a', 2, true];
    	var arreglo2 = [1, 2, 4];
    	var otroArreglo = ['abc', 1, false]
    
    	var nuevaArray = arreglo.concat(arreglo2, [5.25, 100], otroArreglo);
    
    console.log(nuevaArray);
  • .every() verifica si todos los elementos en el arreglo pasan la prueba implementada por la función dada:

    function tamañoValido(elemento, indice, arrreglo) {
      return elemento >= 10;
    }
    [12, 5, 8, 130, 44].every(tamañoValido);   // false
    [12, 54, 18, 130, 44].every(tamañoValido); // true    
  • .filter() Crea un nuevo array con aquellos elementos que cumplan la condición:

    function tamañoValido(elemento) {
      return elemento >= 10;
    }
    var filtrados = [true, 134, 10, 0, null, "Hola"].filter(tamañoValido);
  • .forEach() Se ejecuta la función por cada elemnto del array:

    function logger(element, index, array) {
        console.log("array[" + index + "] = " + element);
    }
    [2, 5, 9].forEach(logger);
  • .indexOf() Devuelve la posición donde se escuentra el elemnto o -1 si no lo encuentra:

    var array = [2, 5, 9];
    var index = array.indexOf(9); // 2
    var index = array.indexOf(12); // -1
  • .join() Une todos los elementos en una cadena:

    var array = ['dato1', 2, , 'masDatos'];
    var datosJuntos = array.join();      // 'dato1,2,masDatos'
    var datosJuntos2 = array.join('');    // 'dato12masDatos'
    var datosJuntos3 = array.join(' + '); // 'dato1 + 2 + masDatos'
  • .lastIdexOf() Devuelve la posición del último elemento que coincide o -1 si no lo encuentra:

    var array = [7, 1, 3, 7];
    array.lastIndexOf(7); // 3
    array.lastIndexOf(2); // -1
  • .reduce() Aplica una función a un acumulador y a cada valor de un vector para reducirlo a un único valor:

    var reduce = [0,-3,1,2,4,6].reduce(function(valorAnterior, valorActual, indice, vector){
      return valorAnterior + valorActual;
    });
    console.log(reduce); // 10
  • .reduceRight() Aplica una función a un acumulador y a cada valor (de izq. a dcha.) de un vector para reducirlo a un único valor:

    var reduceRight = [0,-3,1,2,4,6].reduce(function(valorAnterior, valorActual, indice, vector){
      return valorAnterior + valorActual;
    });
    console.log(reduceRight); // 10
  • .reverse() Invierte el orden de un Array:

    var miArray = ['uno', 2, true, 'más datos...'];
    miArray.reverse(); 
    console.log(miArray) // ["más datos...", true, 2, "uno"]
  • .slice() Devuelve un nuevo Array con un segmento determinado del Array original:

    var frutas = ['Platano', 'Naranja', 'Limón', 'Manzana', 'Mango'];
    var citricos = frutas.slice(1, 3);
    console.info(citricos);
  • .some() Verifica si alguno de los elementos en el arreglo pasan la prueba implementada por la función dada::

    function tamañoValido(elemento, indice, arrreglo) {
      return elemento >= 10;
    }
    [12, 5, 8, 130, 44].some(tamañoValido);   // true
    [12, 54, 18, 130, 44].some(tamañoValido); // true
  • .sort() Ordenar:

    var frutas = ['Platano', 'Naranja', 'Limón', 'Manzana', 'Mango'];
    frutas.sort(); // ["Limón", "Mango", "Manzana", "Naranja", "Platano"]
    
    var miArray = ['uno', 2, true, 'más datos...'];
    miArray.sort(); // [2, "más datos...", true, "uno"]
  • .toLocalString() Retorna como string (configuración regional) todos los elementos:

    var numero = 1337.89;
    var fecha = new Date();
    var miArray = [numero, fecha, 'más datos'];
    
    var arrayConvertida = miArray.toLocaleString(); 
    console.log(arrayConvertida);     
  • .toString() Retorna una cadena de texto con todos los nombres:

    var amigos = ['Luis', 'Carlos', 'Marco', 'Eduardo'];
    console.log(amigos.toString());
  • .unShift() Añade nuevos elementos al principio del array y devuelve la longitud actualizada:

    var miArray = [1, 2];
    
    miArray.unshift(true, "otros datos...");
    console.log(miArray);

Arreglos avanzados

var arreglo1 = ["plátano", "fresa", "lima", "manzana"];
var arreglo2 = ["entrante", "primero", "segundo", "postre"];

var juntandoArreglos = [arreglo1, arreglo2];

function testArreglos () {
    console.log(juntandoArreglos[0][0]);
    console.log(juntandoArreglos[1][3]);
};

Objetos

Objetos Literales

  • Propiedades:

    var miObjeto = {
        cadena: 'esto es una cadena',
        numero: 2,
        booleano: false
    };
  • Métodos:

    var miObjeto = {
        saludar: function(){
    		console.log("hola!");
    	}
    };
  • Trabajando con espacios y caracteres especiales:

    var miObjeto = {
    	nombre: "objeto",
        "año": 2015,
        "estado del sistema": "correcto"
    };
    
    console.log(miObjeto["año"]);
    miObjeto["estado del sistema"] = "fuera de servicio";
    console.log(miObjeto["estado del sistema"]);
  • Acortar objetos:

    var objetoAbreviado = objeto.muy.muy.largo.que.tiene.muchos["metodos y propiedades"];
    
    objetoAbreviado.propiedad1;
    objetoAbreviado.metodo1();

Métodos

  • .defineProperties() Define nuevas o modifica propiedades existentes directamente en el objeto, returnando el objeto.:

    	var miObjeto = {propiedad: "Propiedad original..."}
    Object.defineProperties(miObjeto, {
      "propiedad1": {
        value: true,
        writable: true
      },
      "propiedad2": {
        value: "Cadena de texto",
        writable: false
      }
    });
    console.info(miObjeto);
    miObjeto.propiedad = "Propiedad original Modificada";
    console.info(miObjeto.propiedad);
    miObjeto.propiedad2 = "Cadena de texto... ¿modificada?";
    console.info(miObjeto.propiedad2);
  • .getOwnPropertyDescriptor() Devuelve las detalles de los objetos y métodos del objeto. Undefined en caso de no existir:

    var miObjeto = {
      metodo: function() {
      	console.log(miObjeto.propiedad1)
      },
      propiedad1: "Datos"
    };
    
    console.info(Object.getOwnPropertyDescriptor(miObjeto, 'propiedad1'));
    // Object {value: "Datos", writable: true, enumerable: true, configurable: true}
    
    console.info(Object.getOwnPropertyDescriptor(miObjeto, 'inventado'));
    // undefined
  • .getOwnPropertyNames() Devuelve un array con todos los nombres de las propiedades y métodos del objeto:

    var miObjeto = {
      metodo: function() {
      	console.log(miObjeto.propiedad1)
      },
      propiedad1: "Datos"
    };
    
    console.log(Object.getOwnPropertyNames(miObjeto));
    // ["metodo", "propiedad1"]
  • .isExtensible() Determina si un objeto es extensible:

    var miObjeto = {
      metodo: function() {
      	console.log(miObjeto.propiedad1)
      },
      propiedad1: "Datos"
    };
    
    console.log("¿Se puede extender?", Object.isExtensible(miObjeto));
    
    var sellado = Object.seal(miObjeto);
    console.log("¿Se puede extender?", Object.isExtensible(sellado));
    
    var congelado = Object.freeze(miObjeto);
    console.log("¿Se puede extender?", Object.isExtensible(congelado));
    
    Object.preventExtensions(miObjeto);
    console.log("¿Se puede extender?", Object.isExtensible(miObjeto));
  • .hasOwnProperty() Devuelve true o false si la propiedad existe o no:

    var miObjeto = {
      metodo: function() {
      	console.log(miObjeto.propiedad1)
      },
      propiedad1: "Datos"
    };
    
    console.log("¿Tiene la propiedad \"propiedad1\"?", miObjeto.hasOwnProperty('propiedad1'));
    console.log("¿Tiene la propiedad \"propiedad2\"?", miObjeto.hasOwnProperty('propiedad2'));
  • .propertyIsEnumerable() Devuelve true o false si la propiedad es especificada es enumerable.:

    var miObjeto = {
      metodo: function() {
      	console.log(miObjeto.propiedad1)
      },
      propiedad1: "Datos"
    };
    
    console.log("¿Es enumerable \"propiedad1\"?", miObjeto.propertyIsEnumerable('propiedad1'));
    console.log("¿Es enumerable \"metodo\"?", miObjeto.propertyIsEnumerable('propiedad2'));
  • .toLocaleString() Retorna como string (configuración regional) todas las propiedades:

    var fecha = new Date();
    
    var miObjeto = {
      metodo: function() {
      	console.log(miObjeto.propiedad1)
      },
      propiedad1: "Datos",
      fecha: fecha
    };
    
    miObjeto.toLocaleString()
    console.log("La fecha es ", miObjeto.fecha);

For... in

Itera sobre todas las propiedades de un objeto, en un orden arbitriario.

	var objeto1 = {
		propiedad1: "hola",
		propiedad2: 2,
		propiedad3: false,
		propiedad4: [true,2,5, "..."],
		propiedad5: {
			dato: "más datos..."
		},
		metodo: function(){
			console.log("hola");
		}
	}
	function mostrar_propiedades(objeto, nombreObjeto) {
	   var resultado = "";
	   for (var i in objeto) {
	      resultado += nombreObjeto + "." + i + " = " + objeto[i] + "\n";
	   }
	   return resultado;
	}
	
	mostrar_propiedades(objeto1, "objeto1");

Funciones

  • Propiedad name:

    function miFuncion (){
    // vacia
    };
    
    console.log(miFuncion.name);
  • Declaración y ejecución:

    function dameTrue (){
    return true
    };
    
    function dameFalse () {
    return false
    };
    
    dameTrue();
    dameFalse();
  • this:

    • como función (this contexto window)
      function ambitoGlobal () {
        return this;
      }
      
      ambitoGlobal()
    • como método en un objeto (this contexto objeto al que pertenece el método)
      var objeto = {};
      
      objeto.miMetodo = function () {
        return this;
      }
      
      objeto.miMetodo();
    • como constructor de un objeto (this contexto objeto creado)
    • .apply() y .call() (modificación explícita de this)
  • Argumentos:

    • El exceso de argumentos no es un problema
    • La falta de argumento crea un valor indefinido
      • El Objeto Arguments no es un Array, solo es similar.
        function pruebaArguemntos () {
        console.log(arguments);
        console.info(arguments[0]);
        console.info(arguments[1]);
        }
        
        pruebaArguemntos (1, "vale", true);
        
  • Objeto Arguments

  • Retorno

  function sumaCuadrados (a, b) {
    return (a*a) + (b*b);
  };

Scope

  • Declaración y ejecución:
    var numero = 450;
    var otroNumero = 23;
    
    function sumaCuadrados (a, b) {
    var numero = a;
    var otroNumero = b;
    var calculo = (numero*numero) + (otroNumero*otroNumero);
    console.log("\"numero\" es \""+numero+"\", local");
    console.log("\"otroNumero\" es \""+otroNumero+"\", local");
    };
    
    function verificarGlobales() {
    console.log("\"numero\" es \""+numero+"\", global");
    console.log("\"otroNumero\" es \""+otroNumero+"\", global");
    };

Funciones Avanzadas

  • Anónimas (expresiones):

    var sumaCuadrados = function (a, b) {
    return (a*a) + (b*b);
    };
    
    console.log("El .name de sumaCuadrados es "+sumaCuadrados.name)
  • Funciones como dato:

    function saludo () {
    console.log("hola!");
    };
    
    function lanzar (funcion){
    funcion();
    };
  • Funciones anónimas autoejecutables:

    (function() {
    console.log("hola Amigo/a")
    
    }) (); //ex:Jquery
  • Funciones anónimas con parámetros:

    ( function(quien){
     console.log("hola " + quien);
    })("Amigo/a");
  • Función que devuelve una función anónima:

    • Asignando una variable:

    function saludo(quien){ return function(){ alert("hola " + quien); } } var saluda = saludo("Amigo/a"); saluda();

    
    - Sin asignar una variable:
    ```javascript
    function saludo(quien){
          return function(){
                  alert("hola " + quien);
          }
    }
    saludo("Amigo/a")();
    

Funciones Avanzadas: Anidación

  • Anidación:

    function saludar(quien){
          function alertasaludo(){
                  console.log("hola " +  quien);
          }
          return alertasaludo;
    }
    var saluda = saludar("Amigo/a");
    saluda();
  • Anidación:

    function saludar(quien){
          function alertasaludo(){
                  console.log("hola " +  quien);
          }
          return alertasaludo;
    }
    saludar("Amigo/a")();

Funciones Avanzadas: Recursión

  • Calcular el factorial.

    function factorial(n){
      if(n <= 1){
          return 1
        } else {
          return n * factorial(n-1)
      }
    }
    
    factorial(0); // n! = 1
    factorial(1); // n! = 1
    factorial(2); // n! = 2
    factorial(3); // n! = 6 (3*2*1)
    factorial(4); // n! = 24 (4*3*2*1)
    factorial(5); // n! = 120 (5*4*3*2*1)
    factorial(6); // n! = 720 (...)
    // ...
  • Saber si hoy es un día par o impar.

  var miDiaEs = function() {
      if (new Date().getDate() % 2 == 0) {
          console.info("hoy es un día par");
      } else {
          console.info("hoy es un día impar");
      }
  }
  miDiaEs();

Funciones Avanzadas: Closures

Los closures son funciones que manejan variables independientes. En otras palabras, la función definida en el closure "recuerda" el entorno en el que se ha creado.

No es aconsejable crear innecesariamente funciones dentro de otras funciones si no se necesitan los closures para una tarea particular ya que afectará negativamente el rendimiento del script tanto en consumo de memoria como en velocidad de procesamiento. Closures MDN

  • Fábrica de función:

    function sumador(x) {
    return function(y) {
      return x + y;
    };
    }
    
    var sum1 = sumador(10); //Closure
    var sum2 = sumador(30); //Closure
    
    console.log(sum1(2)); // Devuelve 12
    console.log(sum2(2)); // Devuelve 32
    console.log(sumador(20)(2)); //Devuelve 22
  • Otro ejemplo, ahora temporizado:

    function saludar(segundos){
    var hola = "Hola, Hola!";
    
    setTimeout(function(){
      console.info(hola);
    },segundos*1000);
    }
    
    saludar(2);
  • Otro ejemplo... más útil:

      var varGlobal = "Soy un dato Global";
      var burbuja;
    
      function nivel1() {
        var varInterna = "Soy un dato interno. -> nivel1";
    
        function nivel2() {
          console.log("Estoy dentro de la funcion -> nivel2")
          console.log("Estoy dentro de la funcion -> nivel2 y puedo acceder al nivel1: "+varInterna)
        }
    
        burbuja = nivel2;
    
      }
    
      nivel1();
    
      burbuja();
      console.log("Burbuja recuerda su contexto original")

Funciones Avanzadas: Callbacks

En programación de computadoras, una devolución de llamada o retrollamada (en inglés: callback) es una función "A" que se usa como argumento de otra función "B". Cuando se llama a "B", ésta ejecuta "A". Para conseguirlo, usualmente lo que se pasa a "B" es el puntero a "A". Callbacks en Wikiwand

  • Ejemplo condensado:

    var quieroCallback = function(parametro, callback){
      if ((callback) && (typeof callback === 'function')){
          callback(parametro);
      }
      else
          console.log(parametro, callback);
    }
    
    quieroCallback('a', 'b');
    
    quieroCallback('a', function(val){
      console.log(val);
    });
  • Ejemplo con Jquery:

    $('#elemento').fadeIn('slow', function() {
      // código del callback
    });
  • Otro ejemplo:

    function comerSandwich(elemento1, elemento2, callback) {
      console.info('ñam ñam... empiezo con el sándwich.\n\nMe gusta porque tiene tiene ' + elemento1 + ', ' + elemento2);
      callback();
    }
    
    comerSandwich('jamón', 'queso', function() {
      console.info('Ya terminé...');
    });
  • Ejemplo con Callback opcional:

    function comerSandwich(elemento1, elemento2, callback) {
      console.info('ñam ñam... empiezo con el sándwich.\n\nMe gusta porque tiene tiene ' + elemento1 + ', ' + elemento2);
      
      if (callback) {
          callback();
      }
    
    }
    
    comerSandwich('jamón', 'queso');
  • Sanitizar el Callback:

    function comerSandwich(elemento1, elemento2, callback) {
      console.info('ñam ñam... empiezo con el sándwich.\n\nMe gusta porque tiene tiene ' + elemento1 + ', ' + elemento2);
      
      if (callback && typeof(callback) === "function") {
          callback();
      }
    
    }
    
    comerSandwich('jamón', 'queso');

Funciones Avanzadas: Asincronia

	    function comerSandwich(elemento1, elemento2, callback) {
	      console.info('ñam ñam... empiezo con el sándwich.\n\nMe gusta porque tiene tiene ' + elemento1 + ', ' + elemento2);
	    
	    setTimeout(alarma, 5000);
	    function alarma(){
	      console.log("ring! ring!.. pasaron los 5 segundos!");
	    };
	
	    
	      if (callback && typeof(callback) === "function") {
	          callback();
	      }
	  }
	
	  comerSandwich('jamón', 'queso', function() { 
	      console.log('Ya terminé...');
	  });

Funciones Avanzadas: Funciones anónimas autoejecutadas

  • Sintaxis:
    (function(){
      console.log('Hola Mundo!');
    })();
  • Incluyendo referencias y manipulando otros elementos:
    var myApp = myApp || {};
    
    (function(w, doc, ns){
      
      ns.accesoWindow = function(){
        return w === window;
      };
      ns.accesoDocument = function(){
        return doc === document;
      };
      ns.confirmacion = function(){
        console.log('Hola Mundo! Mis caracteristicas son: \n Acceso a Window: '+this.accesoWindow()+'\n Acceso a Document: '+this.accesoDocument());
      }
    })(window, document, myApp);

    
    // myApp.confirmacion()

Funciones Avanzadas: Memoization

  • Claves:

    • Nos permite "cachear" resultados para agilizar los procesos más complejos
  • Intentaremos resolver la Sucesión de Fibonacci:

    • Fibonacci sin Cachear:
        var fibonacci = function(numero) {
          return numero == 0 ? 0 :
                 numero == 1 ? 1 :
                 fibonacci(numero-1) + fibonacci(numero-2);
        };
        console.log( "fibonacci(34) = " + fibonacci(34));
    • Fibonacci cacheado (No Optimizado):
        var fibonacci = function(numero) {
          return numero == 0 ? 0 :
                 numero == 1 ? 1 :
                 fibonacci(numero-1) + fibonacci(numero-2);
        };
        
        var fibonacci_cache = function(numero, cache) {
          if(!cache[numero]) {
            cache[numero] = fibonacci(numero);
          }
          return cache[numero];
        };
        
        var cache = {};
        console.warn("fibonacci_cache(34, cache) = " + fibonacci_cache(34, cache));
        console.info("fibonacci_cache(34, cache) = " + fibonacci_cache(34, cache));
    • Fibonacci cacheado (Optimizado):
        var fibonacci = function(numero) {
          return numero == 0 ? 0 : 
                 numero == 1 ? 1 :
                 fibonacci(numero-1) + fibonacci(numero-2);
        };
        
        var cachify = function(f, cache) {
          return function(numero) {
            if(!cache[numero]) {
              cache[numero] = f(numero);
            }
            return cache[numero];
          };
        };
        
        var cache = {};
        fibonacci = cachify(fibonacci, cache);
        
        console.info("fibonacci(1476) = " + fibonacci(1476), cache );
        console.info("fibonacci(1476) = " + fibonacci(1476), cache );

Trabajando con APIs

CRUD

  • Create:
    • Method (POST):
      • Respuesta 200 - OK
      • Respuesta 204 - Sin contenido
      • Respuesta 404 - No encontrado
      • Respuesta 409 - Conflicto, ya existe
  • Read:
    • Method (GET):
      • Respuesta 200 - OK
      • Respuesta 404 - No encontrado
  • Update:
    • Method (PUT):
      • Respuesta 200 - OK
      • Respuesta 204 - Sin contenido
      • Respuesta 404 - No encontrado
  • Delete:
    • Method (DELETE):
      • Respuesta 200 - OK
      • Respuesta 404 - No encontrado

HTTP Protocolo

AJAX

Ajax comparación

Con Jquery

    function peticionJqueryAjax (url) {

	    $.ajax({
	        dataType: "json",
	        url: url,
	    })
	     .done(function( data, textStatus, jqXHR ) {
	         if ( console && console.log ) {
	             console.log( "La solicitud se ha completado correctamente." );
	             console.log( data );
	         }
	     })
	     .fail(function( jqXHR, textStatus, errorThrown ) {
	         if ( console && console.log ) {
	             console.log( "La solicitud a fallado: " +  textStatus);
	         }
	    });
	
	}
	
	peticionJqueryAjax ("<---URL---->");

Vainilla JS

  • readyState:
    • 0 es uninitialized
    • 1 es loading
    • 2 es loaded
    • 3 es interactive
    • 4 es complete
    function peticionAjax(url) {
        var xmlHttp = new XMLHttpRequest();

        xmlHttp.onreadystatechange = function() {

            if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
                console.info(JSON.parse(xmlHttp.responseText));
            } else if (xmlHttp.readyState === 4 && xmlHttp.status === 404) {
                console.error("ERROR! 404");
                console.info(JSON.parse(xmlHttp.responseText));
            }
        };
        xmlHttp.open("GET", url, true);
        xmlHttp.send();
    }

    peticionAjax("<---URL---->");

JSON

  • JSON.parse()

    • Analiza la cadena y retorna los valores
  • JSON.stringify()

    • Analiza los valores y retorna una cadena

JSONP

  • json (formato)

      { foo: 'bar' }
  • callback (cliente)

      mycallback = function(data){
        alert(data.foo);
      };
  • peticion (cliente)

      var url = "http://www.example.net/sample.aspx?callback=mycallback";
  • respuesta (servidor)

      mycallback({ foo: 'bar' });
  • Ejemplo de CORS y JSONP con php de formandome

      <?php
      header('content-type: application/json; charset=utf-8');
      header("access-control-allow-origin: *");
       
      //Cadena de conexión:
      $connect = mysql_connect("localhost", "usuario", "pwd")
      or die('Could not connect: ' . mysql_error());
       
      //seleccionamos bbdd:
      $bool = mysql_select_db("database", $connect);
      if ($bool === False){
         print "No puedo encontrar la bbdd: $database";
      }
       
      //inicializamos el cliente en utf-8:
      mysql_query('SET names utf8');
     
      $query = "SELECT * FROM futbolistas";
       
      $result = mysql_query($query) or die("SQL Error: " . mysql_error());
      $data = array();
      // obtenemos los datos:
      while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
          $data[] = array(
              'id' => $row['id'],
              'nombre' => $row['nombre'],
              'apellido' => $row['apellido'],
              'posicion' => $row['posicion'],
              'equipo' => $row['equipo'],
              'dorsal' => $row['dorsal'],
              'desc' => $row['desc'],
      	'imagen' => $row['imagen']
            );
      }
       
      //codificamos en json:
      $json = json_encode($data);
       
      //enviamos json o jsonp según venga o no una función de callback:
      echo isset($_GET['callback'])
          ? "{$_GET['callback']}($json)"
          : $json;
      ?>

Soporte en cliente (librerías):

  • Jquery:
      // Using YQL and JSONP
      $.ajax({
          url: "http://query.yahooapis.com/v1/public/yql",
       
          // The name of the callback parameter, as specified by the YQL service
          jsonp: "callback",
       
          // Tell jQuery we're expecting JSONP
          dataType: "jsonp",
       
          // Tell YQL what we want and that we want JSON
          data: {
              q: "select title,abstract,url from search.news where query=\"cat\"",
              format: "json"
          },
       
          // Work with the response
          success: function( response ) {
              console.log( response ); // server response
          }
      });  
  • jsonp.js de Przemek Sobstel
  • J50Npi.js de Roberto Decurnex

Ejercicios

1 - Sacar en el html la respuesta de OMDB para la pelicula Hackers

	 function peticionAjax (movieName) {
	  var xmlHttp = new XMLHttpRequest(),
	                cURL = 'http://www.omdbapi.com/?t='+movieName+'&y=&plot=short&r=json';
	
	            xmlHttp.onreadystatechange = function () {
	
	                if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
	                    var datos = (JSON.parse(xmlHttp.responseText));
	                    var contenido = "";
	                    contenido += "<h1>"+datos.Title+"</h1>"
	                    contenido += "<p>"+datos.Plot+"</p>"
	                    document.body.innerHTML = contenido;
	                } else if (xmlHttp.readyState === 4 && xmlHttp.status === 404) {
	                    console.error("ERROR! 404");
	                    console.info(JSON.parse(xmlHttp.responseText));
	                }
	            };
	
	            xmlHttp.open( "GET", cURL, true );
	            xmlHttp.send();
	}
	
	peticionAjax("Hackers");

2 - Sacar en el html el tiempo meteorológico de Madrid, Barcelona y Valencia. Nota: http://openweathermap.org te será de gran ayuda, busca la solución al error 401

	var contenido = "";
  	function temperaturaCiudad (ciudad) {
        var xmlHttp = new XMLHttpRequest(),
        APIKey = '', // Puedes usar una cuenta gratuita -> http://openweathermap.org/price
        cURL = 'http://api.openweathermap.org/data/2.5/weather?q='+ciudad+'&APPID='+APIKey;
    
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
                var datos = (JSON.parse(xmlHttp.responseText));
	              contenido += "<h1>"+datos.name+"</h1>"
	              contenido += "<p>"+datos.weather[0].description+"</p>"
	              document.body.innerHTML = contenido;
            } else if (xmlHttp.readyState === 4 && xmlHttp.status === 404) {
                datos = JSON.parse(xmlHttp.responseText);
                console.error("ERROR! 404");
                console.info(datos);
            }
        };
    
        xmlHttp.open( "GET", cURL, true );
        xmlHttp.send();
    }
    
    temperaturaCiudad("Madrid");
    temperaturaCiudad("Barcelona");
    temperaturaCiudad("Valencia");

3 - Jugando con datos abiertos, saquemos los detalles de todos los cuadros eléctricos de Gijón por consola.

    function peticionAjax (url) {
	  var xmlHttp = new XMLHttpRequest();
	
	            xmlHttp.onreadystatechange = function () {
	
	                if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
	                    var datos = (JSON.parse(xmlHttp.responseText));
                        console.log(datos)
	                } else if (xmlHttp.readyState === 4 && xmlHttp.status === 404) {
	                    console.error("ERROR! 404");
	                    console.info(JSON.parse(xmlHttp.responseText));
	                }
	            };
	
	            xmlHttp.open( "GET", url, true );
	            xmlHttp.send();
	}
    
    
    // Utilizamos un proxy como http://crossorigin.me para solucionar el problema de CORS	
	peticionAjax("http://crossorigin.me/http://opendata.gijon.es/descargar.php?id=163&tipo=JSON");
// Podemos encontrar errores en las respuestas.
// cuadromando[5] ...

    calle: "Faustina &#193;lvarez Garc&#237;a"
    latitud: 43.526376045
    longitud: -5.685764873
    numero: ""
    potencia_w_: 17321

// ...

Programación dirigida a eventos

La programación dirigida por eventos es un paradigma de programación en el que 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.

Para entender la programación dirigida por eventos, podemos oponerla a lo que no es: mientras en la programación secuencial (o estructurada) es el programador el que define cuál va a ser el flujo del programa, en la programación dirigida por eventos será el propio usuario —o lo que sea que esté accionando el programa— el que dirija el flujo del programa. Aunque en la programación secuencial puede haber intervención de un agente externo al programa, estas intervenciones ocurrirán cuando el programador lo haya determinado, y no en cualquier momento como puede ser en el caso de la programación dirigida por eventos. Wikiwand

  • Ejemplo:
     	var eventos = {
     		agregar: null,
     		quitar: null,
     		manejador: function(evento) {
     	        console.group("Manejador de Eventos");
     		        console.log("-----------------------------");
     	            console.log("Type: " + evento.type); // Tipo
     	            console.log("Bubbles: " + evento.bubbles); // sube por el DOM
     	            console.log("Cancelable: " + evento.cancelable);
     	            console.log("CurrentTarget: ", evento.currentTarget);
     	            console.log("DefaultPrevented: " + evento.defaultPrevented);
     	            console.log("EventPhase: " + evento.eventPhase);
     	            console.log("Target: ", evento.target);
     	            console.log("TimeStamp: " + evento.timeStamp);
     	            console.log("IsTrusted: " + evento.isTrusted); // true - Usuario o false - Script
     	            console.log("=============================");
     	        console.groupEnd();
     	    }
     	}
     	
     	// Init-time branching (Patrón)
     	if (typeof window.addEventListener === 'function') {
     	    eventos.agregar = function(el, type, fn) {
     	    	el.addEventListener(type, fn, false);
     		};
     	    eventos.quitar = function(el, type, fn) {
     	    	el.removeEventListener(type, fn, false);
     	    };
     	} else { // Soporte para IE8
     	    eventos.agregar = function(el, type, fn) {
     	        el.attachEvent('on' + type, fn);
     	    };
     	    eventos.quitar = function(el, type, fn) {
     	        el.detachEvent('on' + type, fn);
     	    };
     	}
     	
     	eventos.agregar(document.body, 'click', function (e) {
     		var color = 'rgb(' + Math.floor((Math.random() * 255))+ ',';
     		color += Math.floor((Math.random() * 255)) + ',';
     		color += Math.floor((Math.random() * 255)) + ')';
     		document.body.style.backgroundColor= color;
     		console.info("Nuevo color:", color);
     	})

4 - Utiliza Ajax para posicionar al usuario y las estaciones de BiciMad en un mapa. Recursos:

Capturas

usuario detalles

estación detalles

5 - Crea una web que nos permita ver los detalles almacenados en IMBD de una pelicula partiendo únicamente del título Recursos: