Primeros conceptos

3-3-2020

La primera clase desarrolló con bastante dinamismo, para ser de mera presentación del tema.

 

Asincrónico vs. Sincrónico

Primero se explicó que Javascript fue un lenguaje bastante relegado en sus comienzos, entre otras razones porque Microsoft nunca lo apoyó, y empezó a cobrar vuelo cuando Google y Facebook entraron de lleno a respaldarlo. La cuestión pasaba porque se trataba de un lenguaje con muchos errores y al que había que hacerle muchos "hacks" para que funcionara, sin mencionar que Internet Explorer siempre generaba conflictos y para que un mismo evento funcionara en todos los navegadores se requería mucho esfuerzo y horas de dedicación.

Aparece en escena la versión 6 de JS que viene a corregir muchos de estos errores, además que Microsoft teme quedarse afuera y comienza a apoyarlo.

En pocas palabras, uno de los grandes cambios de mentalidad que representa usar JS en lugar de un lenguaje de servidor (por ejemplo PHP), es que se maneja en forma asincrónica en lugar de sincrónica.

Tradicionalmente, el navegador (el cliente) se comunicaba con el servidor para pedirle cosas cada vez que alguien se conectaba a una página web. Le pedía la información alojada en una base de datos, le pedía que trajera archivos y los mostrara, etc.

Este ida y venida de información desde el request del frontend a la response del backend implicaba un trabajo sincrónico, donde todo se congelaba hasta esperar que la página cargara. Esperar a que todo llegara.

Javascript permite trabajar con varios requests al mismo tiempo y no se queda esperando a que cada uno cargue para comenzar con el otro.

El ejemplo que dieron en clase fue por demás gráfico: Imaginemos que estamos es un restaurante.

Un restaurante sincrónico, asigna un mozo a cada comensal. Mientras el comensal está pensando en qué ordenar, el mozo está allí esperando por él. El mozo es exclusivo de cada mesa. El servicio es excelente, ya que el mozo está siempre listo para servirnos, pero es sumamente caro, ya que necesitamos muchos mozos (o un servidor muy eficiente) para poder atender mcuhas mesas. Y si de pronto viene un montón de gente por un evento? La gente esperará afuera hasta que algún mozo se desocupe.

Por otra parte el restaurante asincrónico tiene un sólo mozo, que atiende todas las mesas. Mientras un comenal piensa su pedido, el mozo está entregando el postre a otro comensal. Deja eso y toma la orden de otra mesa. Y luego, cuando estamos listos, toma nuestra orden.

Es por ello que muchas veces vemos que una página carga y cierta parte de ésta no ha cargado aún, o carga luego, o se actualiza sin necesidad de refrescar el navegador, es porque está trabajando en forma asincrónica.

 

LAMP vs. MEAN

El entorno tradicional LAMP en el que uno está acostumbrado a trabajar en, por ejemplo, PHP, se compone de:

Linux (el sistema operativo)

Apache (el servidor)

MySQL (la base de datos relacional)

Php (el lenguaje de programación)

Por otra parte, con JS, al entorno se lo conoce con el acrónimo MEAN:

MongoDB (Base de datos no relacional)

Express (servidor)

Angular (lenguaje, en realidad es JS, pero con el framework Angular sobre éste)

NodeJS (sistema operativo)

Lo interesante es que ya no necesitamos un sistema operativo, ya que nodeJS hace las veces de éste, es decir Javascript no requiere usar Linux o Windows en su caso. Y de hecho, los navegadores funcionan en todos los sistemas operativos, y JS funciona desde el navegador (ahora también desde el servidor con NodeJS, pero no me meto en node por el momento).

 

Frameworks

Google promueve el uso de Angular, el cual desde la versión 2 sufrió una especie de forking, porque cambió radicalmente la forma de trabajo de este framework. Facebook creó el framework React y Microsoft porsu parte creó y apoya typeScript.

A todo esto se suma el framework VUE, creado por un ex ingeniero de Google que tomó lo mejor de todos, y aparentemente es mucho mejor que los otros frameworks, pero al no tener detrás una empresa, sino la comunidad de usuarios, muchas empresas no lo han adoptado todavía porque temen falta de soporte futuro.

 

Problemas resueltos

ECMAScript 6 (es decir JS en su versión 6), vino a resolver mcuhos pequeños y grandes errores del lenguaje.

Uno de los problemas mayores era la cuestión del SCOPE, es decir, el comportamiento de las variables dependiendo de su ubicación en un determinado bloque de código.

Una variable (var $miVariable) en un bloque anónimo o condicional es global, mientras que solamente dentro de una función una variable tenía su condición de ser local. Esto era considerado un error, y ahora se resolvió con la posibilidad de crear variables usando let (para que cada variable creada con let fuera local y nunca global) y const (para crear constantes, es decir variables que no varían su contenido y se declaran una sola vez).

La estructura de creación es la misma:

var $miVariable = 'abc';

let $otraVariable = 'mi variable local';

const $miContante = 'mi contenido constante';


//Ejemplos con var

//------------------------
//CUERPO DE CÓDIGO ANÓNIMO
//------------------------
{
    const va = 'anónimo'
    //va = 'anómino update'
    console.log(va)
}
//console.log(va)

//----------------------------
//CUERPO DE CÓDIGO CONDICIONAL
//----------------------------
if(true){
    const vc = 'condicional'
    console.log(vc)
}
//console.log(vc)

//--------------------------
//CUERPO DE CÓDIGO FUNCIONAL
//--------------------------
function foo(){
    const vf = 'funcional'
    console.log(vf)
}
foo()
console.log(vf)


Una cosa que encontré interesante y perturbadora a la vez es que podemos prescindr "casi" siempre del punto y coma final. Ello me genera algo de confusión con PHP, donde es necesario, pero reconozco que es mucho más sencillo escribir así, sin punto y coma. Mucho más rápido.

Otro error era el elemento this que perdía la referencia en algunas situaciones, y ello se solucionó con la creación de las "arrow functions".

//------------------------
//ARROW FUNCTION
//------------------------

//Esta es la forma tradicional de escribir las funciones
function dobleDe(a) {
    return 2*a
}

//También así, metiéndolas dentro de una variable (en este caso una constante) 
const dobleDe = function(a) {
    return 2*a
}
console.log(dobleDe(12))

//Y aquí está la arrow function, más corta

//si toda la función abarca un sólo renglón, no necesitamos llaves
//y si no tiene parámetros tampoco necesitamos los paréntesis cuando es una sola línea
//y también, cuando hay una sola línea, el retun está implícito
const dobleDe = a => 2*a


const printMsg = () => {
    console.log('Soy un mensaje')
}

//y si tenemos varios parámetros sí necesitamos los paréntesis y los separamos con comas
const sumar = (a,b,c) => a+b+c
console.log(sumar(4,5,6))

// El this, sin las arrow functions perdía su referencia

var persona = (function() {
    this.nombre = 'Pepe'
    this.edad = 32
    var that = this

    return {
           getPersona : function() {
            console.log(this)
            return {edad: that.edad, nombre: that.nombre }
           } 
 
})()
console.log(persona.getPersona().nombre)
console.log(persona.getPersona().edad)


// Con las arrow functions eso ya no pasa:
var persona = (function() {
    this.nombre = 'Pepe'
    this.edad = 32

    return {
        getPersona : () => ({edad: this.edad, nombre: this.nombre })
    }
})()
console.log(persona.getPersona().nombre)
console.log(persona.getPersona().edad)

Afortunadamente veremos eso en detalle en clases posteriores.