55

Resumen y Guía del Curso

<h1>Documentación de Fundamentos Javascript</h1>

Fuentes: Platzi, Git, GitHub, npm, nodejs, Facebook

<h2>Importante</h2>

El documento presente no es propiedad intelectual mia, es una recopilación de datos tomados durante el desarrollo del curso de Fundamentos de Javascript de Platzi (https://platzi.com/clases/fundamentos-javascript/). Durante el curso use mensiones e información de los videos, comentarios, enlaces, información de otros sitios e información de otros cursos. Si usted cree que es necesario que su mención en el documento sea necesaria comuniquemelo a [email protected] citando el texto del documento y adjuntarlo a la fuente original. Posteriormente actualisare el documento.

Por favor no usar este material de manera comercial o lucrativa. Este documento es de apoyo educativo y de uso personal. La información escrita no es necesariamente correcta o exenta de errores tanto ortográficos o informativos.

Si desea colaborar con el crecimiento de este documento y sus temas puedes enviarme un email a [email protected] indicando los cambios. Yo me encargare de actualizar el documento.

<h1>Índice</h1>

[TOC]

<h1>Fundamentos</h1>
console.log('hola mundo!');
console.log("El área de un triángulo de base 5 y altura 7 es: " + 5 * 7 / 2);

<h2>Funciones</h2>
letbase = 5;
let altura = 7;

const trianguloArea = (base, altura) => base * altura / 2;

console.log(`El area de un triángulo de base ${base} y altura ${altura} es: ${trianguloArea(base, altura)}`);

<h3>Variables</h3>

Podemos ver que ahora se pueden declarar las variables con let las cuales solo existirán en el contexto en el que hayan sido creadas. Por lo tanto si se declaran dentro de un if o una función o cualquier tipo de llaves estas solo funcionan dentro del mismo.

Ahora disponemos de var como variable global o local dependiendo de donde se declare, let para variables de contexto, const como constantes y si no lo indicamos esta variable será global.

<h3>Arrow Functions</h3>

Las funciones ahora se llaman funciones de arrow functions y que poseen la siguiente sintaxis:

var nameFunction = ([parameters]) => { return value };

Donde var pues ser var/let/const nameFunction es el nombre de la función y se marca los paréntesis para los parámetros. Las llaves son opcionales si solo es una linea de codigo y no hace falta poner return si resuelve un valor.

<h3>Strings</h3>

Ahora el string puede verse representado en string donde permite insertar codigo dentro del mismo utilizando ${ //code }

<h4>Ejemplos extras</h4>
/*Área Circulo*/let radio = prompt(`Radio del Ciculo`);
const circleArea = (radio) => Math.PI * Math.pow(radio, 2);
console.log(`El area del circulo con radio de ${radio} es: ${circleArea(radio)}`);

/*Área Cuadrado*/let lado = prompt(`Lado del Cuadrado`);
const squareArea = (lado) => Math.pow(lado, 2);
console.log(`El area del cuadrado con lado de ${lado} es: ${squareArea(lado)}`);

/*Área Rectangulo*/let base = prompt(`Base del Rectangulo`);
let lado = prompt(`Lado del Rectangulo`);
const rectangleArea = (lado,base) => lado * base;
console.log(`El area del Rectangulo con lado de ${lado} y base de ${base}
es: ${rectangleArea(lado,base)}`);

<h2>Condicionales</h2>
const 
movieName = 'Star Wars: El despertar de la fuerza',
moviePG = 13,

nameSacha = 'Sacha',
ageSacha = 26,

nameSanti = 'Santi',
ageSanti = 12const canWatchMovie = (name, age, isWithAdult = false) => {
  if (age >= moviePG) {
    alert(`${name} puede pasar a ver ${movieName}`)
  }elseif (isWithAdult){
    alert(`${name} puede pasar a ver ${movieName}.
  Aunque su edad es ${age}, se encuentra acompañado/a por un adulto.`)
  } else {
    alert(`${name} no puede pasar a ver ${movieName}.
  Tiene ${age} años y nesesita ${moviePG}`)
  }
}

canWatchMovie(nameSacha, ageSacha)
canWatchMovie(nameSanti, ageSanti, true)

<h2>Definir variables</h2>

Nótese que la definición de distintas variables del mismo tipo son separadas por comas después de su asignación de valor.

const 
movieName = 'Star Wars: El despertar dela fuerza',
moviePG = 13,

<h2>Codigo</h2>

Javascript puede escribirse con puntos y comas o sin ellos

<h2>Parámetros</h2>

Los parámetros pueden ir definidos por default para no poseer el valor undefined.

(name, age, isWithAdult = false) => { ...

<h2>If, else & If else</h2>

Se puede realizar if concatenados por else if

if (age >= moviePG) {
  alert(`${name} puede pasar a ver ${movieName}`)
}elseif (isWithAdult){
  alert(`${name} puede pasar a ver ${movieName}.
Aunque su edad es ${age}, se encuentra acompañado/a por un adulto.`)
} else {
  alert(`${name} no puede pasar a ver ${movieName}.
Tiene ${age} años y nesesita ${moviePG}`)
}

<h2>Manipulación de Strings</h2>

El objetivo es traducir palabras con el fin de “crear un nuevo idioma” utilizando ciertas reglas.


var platzom = (str) => {

  let translation = str;// Si la palabra termina en ar, se quitan esos caracteresif(str.toLowerCase().endsWith('ar')){
    translation = str.slice(0, -2);
  }

  // Si la palabra inicia con Z, se le añade "pe" al finalif(str.toLowerCase().startsWith('z')){
    translation += 'pe';
  }

  // Si la palabra traducida tiene 10 o más letras,// se debe partir a la mitad y unir con un guión del medioif(translation.length >= 10){
    let halft = Math.round(translation.length / 2);
    let firstHalf = translation.slice(0, halft);
    let secondHalf = translation.slice(halft, translation.length);
    translation = `${firstHalf}-${secondHalf}`;
  }

  constreverse = (str) => str.split('').reverse().join('');
  const minMay = str => str.split('').map(c => str.indexOf(c) % 2 == 0 ? c.toUpperCase() : c.toLowerCase()).join('');if (str == reverse(str.toLowerCase())) {
    return minMay(str)
  }

  return translation;
}
console.log(platzom("Programar")) // Program
console.log(platzom("Zorro")) // Zorrope
console.log(platzom("Zarpar")) // Zarppe
console.log(platzom("abecedario")) // abece-dario
console.log(platzom("sometemos")) // SoMeTeMoS
<h2>While</h2>
let vidaGoku = 100;
let vidaSuperman = 100;
const min_power = 5;
const max_power = 12;
const ambosSiguenVivos = () => vidaGoku > 0 && vidaSuperman > 0;
const calcularGolpe = () => Math.round(Math.random() * (max_power - min_power) + min_power);
const gokuSigueVivo = () => vidaGoku > 0let round = 0;

while(ambosSiguenVivos())
{
  round++
  console.log(`Round: ${round}`)

  const golpeGoku = calcularGolpe();
  const golpeSuperman = calcularGolpe();

  if (golpeGoku > golpeSuperman)
  {
    console.log(`Goku ataca a Superman con un golpe de ${golpeGoku}`);
    vidaSuperman -= golpeGoku;
    console.log(`Superman queda en ${vidaSuperman} puntos de vida`);
  }
  else
  {
    console.log(`Superman ataca a Goku con un golpe de ${golpeSuperman}`);
    vidaGoku -= golpeSuperman;
    console.log(`Goku queda en ${vidaGoku} puntos de vida`);
  }
}
if(gokuSigueVivo())
{
  console.log(`Goku gano la pelea. su vida es de: ${vidaGoku}`);
}
else
{
  console.log(`Superman gano la pelea. su vida es de: ${vidaSuperman}`);
}

<h2>Date</h2>
const dias =
[
  "domingo",
  "lunes",
  "martes",
  "miercoles",
  "jueves",
  "viernes",
  "sabado"

]

const nacimiento = newDate(0000, 00, 0);const hoy = newDate();const tiempomil = hoy - nacimiento
const tiemposeg = tiempomil /1000const tiempomin = tiemposeg / 60const tiempohor = tiempomin / 60const tiempodias = tiempohor / 24const tiempoyear = tiempodias / 365const proximo = newDate(hoy.getFullYear(), nacimiento.getMonth(), nacimiento.getDate())
console.log(dias[proximo.getDay()])

<h2>Objectos</h2>
const p1 = {
  x: 0,
  y: 4
}

const p2 = {
  x: 3,
  y: 0
}

functiondistancia(p1, p2) {
  const x = p1.x - p2.x
  const y = p1.y - p2.y

  returnMath.sqrt(x * x + y * y)
}
console.log(distancia(p1, p2))
console.log(distancia(p1, { x: 20, y: -7 }))
console.log(distancia(p1, { horizontal: 20, vertical: -7 })) // NaN
<h3>Method</h3>
const p1 = {
  x: 0,
  y: 4,
  moverEnX(x) {
    this.x += x
  },
  moverEnY(y) {
    this.y += y
  }
}

const p2 = {
  x: 3,
  y: 0,
  moverEnX: function (x) { this.x += x },
  moverEnY: function (y) { this.y += y }
}

functiondistancia(p1, p2) {
  const x = p1.x - p2.x
  const y = p1.y - p2.y

  returnMath.sqrt(x * x + y * y)
}
console.log(distancia(p1, p2))
p1.moverEnX(10)
console.log(distancia(p1, p2))
p2.moverEnY(-4)
console.log(distancia(p1, p2))

<h3>Prototipos - Clases de puntos</h3>

prototype permite extender un método de una clase u objeto creado.

functionPunto(x, y) {
  this.x = x
  this.y = y
}
Punto.prototype.moverEnX = functionmoverEnX(x) {
  this.x += x
}
Punto.prototype.moverEnY = functionmoverEnY(y) {
  this.y += y
}
Punto.prototype.distancia = functiondistancia(p) {
  const x = this.x - p.x
  const y = this.y - p.y

  returnMath.sqrt(x * x + y * y)
}

const p1 = new Punto(0, 4)
const p2 = new Punto(3, 0)

console.log(p1.distancia(p2))
console.log(p2.distancia(p1))
p1.moverEnX(10)
console.log(p1.distancia(p2))
p2.moverEnY(-4)
console.log(p1.distancia(p2))

<h2>Clases</h2>

classPunto{
  constructor(x,y) {
    this.x = x
    this.y = y
  }
  moverEnX(x) {
    this.x += x
  }
  moverEnY(y) {
    this.y += y
}

const p1 = new Punto(0,4)
const p2 = new Punto(3,0)

<h2>Operaciones con arrays</h2>
functionsuma(...params){
  return params.reduce((acumulativo, actual) => {acumulativo + actual}, 0)
}

suma(4,5,6,23,26,7,8)
functiondoble(...params){
  return params.map(x=>x*2)
}

doble(2,3,4,5,6,7,5)

const pares = (...numeros) => numeros.filter(x=> x % 2 == 0)

<h2>Closures</h2>

Los closure son funciones que recuerdan el entorno en el cual fueron creadas, esto quiere decir que al llamar la función van a recordar las variables que tenían en ese momento.


functionsaludarFamilia(apellido) {
  returnfunction(nombre) {
    console.log(`Hola ${nombre} ${apellido}`)
  }
}

let saludarPerez = saludarFamilia(\'perez\');


generaPrefijo = prefijo => valor => prefijo + valor;
const re = generaPrefijo("re");
re("malo");
<h2>This, _this y los arrow functions</h2>

Los arrows functions permiten arrastrar el valor this dentro de la functions ForEach. Se recomienda utilizar los arrow functions siempre que se puedan.


classPersona{
  constructor(nombre, amigos = []) {
    this.nombre = nombre
    this.amigos = amigos
  }

  listarAmigos() {
    const _this = thisthis.amigos.forEach((amigo) => {
      // console.log(`Hola, mi nombre es ${_this.nombre} y soy amigo de ${amigo}`)console.log(`Hola, mi nombre es ${this.nombre} y soy amigo de ${amigo}`)
    }/* .bind(this) */)
  }
}

const sacha = new Persona("Sacha", [ "Pedro", "Juan", "Pepe" ])

<h2>Bind</h2>

Con el bind podemos definir el contexto this de una function.

classToggable{
  constructor(el) {
    // inicializar el estado internothis.el = el
    this.el.innerHTML = 'Off'this.activated = falsethis.onClick = this.onClick.bind(this)
    this.el.addEventListener('click', this.onClick)
  }

  onClick(ev) {
    this.activated = !this.activated
    this.toggleText()
  }

  toggleText() {
    this.el.innerHTML = this.activated ? 'On' : 'Off'
  }
}

const button = document.getElementById('boton')

const miBoton = new Toggable(button)

<h2>call y apply</h2>

los métodos call y apply nos permiten definir el contexto de una function

const sacha = {
  nombre: 'Sacha',
  apellido: 'Lifszyc'
}

functionsaludar(veces, uppercase) {
  let str = `Hola ${this.nombre}${this.apellido}`
  str = uppercase ? str.toUpperCase() : strfor (let i = 0; i < veces; i++) {
    console.log(str)
  }
}

const params = [3, true]
saludar.call(sacha, ...params)

<h2>ECMAScript</h2>

El estándar en el que se basa JavaScript.

Comenzó llamándose LiveScript para lo que se mostraba al cliente.

Java != JavaScript

Se llamó ECMAScript porque fue desarrollado por ECMA, una empresa dedicada a telecomunicaciones.

ECMA-262

Sus primeras versiones fueron lanzadas en los 90’s.

En este momento se está creando ECMAScript 2018.

Si escribimos código con ECMAScript tiene que ser compatible con el navegador en el que queremos que corra.

<h2>Babel</h2>

Usa JavaScript de la próxima generación hoy mismo.

Babel es una herramienta que te permite hacer compatible el código que usa funcionalidades de ECMAScript con los diferentes navegadores.

Para poder utilizar Babel debes tener instalado Node.

<h2>Modulo</h2> <h3>Que es un Módulo?</h3>

Paquetes de código que permite dependencias y fuentes.

<h3>¿Por qué queremos escribir un módulo?</h3>

Encapsulamiento: Manejar fragmentos de códigos desacoplados del resto, enfocándose en una tarea específica.

Dependencias: “No inventar la rueda”. Poder requerir módulos y utilizar existentes.

<h3>Módulos en ECMA 2015</h3>
// square.jsimport triangle from'triangle'exportfunctiondiagonal(x) {
  return triangle.hypotenuse(x, x)
}
// index.jsimport square from'square'const side = 7console.log(`La diagonal de un cuadrado de ${side}x${side} 
mide ${square.diagonal(side)}`)

<h2>EventLoop</h2> <h3>Callbacks</h3>

Hay métodos que nos permiten ejecutar procesos de manera asíncrona, entre ellos setTimeout que nos permite ejecutar una función de manera asíncrona tiempo después de su llamado

console.log('first');
setTimeout(function(){console.log('timeout')}, 5000);
console.log('last');

<h3>Callbacks externos</h3>

Para hacer una llamada a una API desde js se utiliza el objeto XMLHttpRequest que permite realizar HTTP request a otras páginas.

functionget(URL, callback){
  const xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    const DONE = 4const OK = 200if (this.readyState === DONE) {
      if(this.status === OK){
        //Todo OK
        callback(null, JSON.parse(this.responseText))
      }else {
        //Jubo un error
        callback(newError(`Se produjo un error al realizar el request ${this.status}`))
      }
    }
  }

  xhr.open('GET', URL);
  xhr.send(null);
}

/* Funcion para tratar el error */functionhandleError(err){
  console.log(`Request failed: ${err}`)
}

/*llamada al metodo */get('http://www.swapi.co/api/people/1/', functiononResponse(err, luke){
  if(err) return handleError(err)

  /* Para traer el mundo */get(luke.homeworld, functiononHomeworldResponse(err, homeworld){
    if(err) return handleError(err)

    luke.homeworld = homeworld
    console.log(`${luke.name} nació en ${luke.homeworld.name}`)
  })

  console.log(`Request succeded`)
  console.log('luke', luke)
})

<h3>Promise</h3>

Las promesas otorgan un mejor formato para request asyn

const http = {}
http.get = function(URL) {
  returnnew Promise((resolve, reject) =>{
    const xhr = new XMLHttpRequest()

    const DONE = 4
    const OK = 200
    xhr.onreadystatechange = function() {  
      if(this.readyState === DONE){
        if(this.status === OK){
          resolve(JSON.parse(this.responseText))
        }else{
          reject(new Error(`Errorin HTTP Request: ${this.status} / ${this.readyState} / ${this}`))
        }
      }
    }

    xhr.open('GET', URL)
    xhr.send(null)
  })
}
viewSWPeople = function(id) {
  const urlAPI_StarWars = 'http://www.swapi.co/api/'
  fetch(urlAPI_StarWars + 'people/' + id)
  .then(res => res.json())
  .then((res) => {
  console.log(res.name)
  return fetch(res.homeworld)
  })
  .then(res => res.json())
  .then((res) => {
    console.log(res.name)
  })
  .catch((err) => {
    console.log(err.message)
  })
}
viewSWPeople(1)

<h3>Async / await</h3>

A su vez se puede re-escribir el código utilizando async. Aunque este se incluirá en ECMA 2017

asyncfunctiongetPeopleSW(){
    try{
      const idpeople = 1const urlAPI_StarWars = `http://www.swapi.co/api/people/${idpeople}`const res = await fetch(urlAPI_StarWars)
      const people = await response.json()

      const resHomeWorld = await fetch(people.homeworld)
      people.homeworld = await resHomeWorld.json

      console.log(`${people.name} born in ${people.homeworld}`)
    } catch (err) {
      console.log(err.message)
    }

}

<h2>Estructuras de datos y funciones avanzadas</h2> <h3>Funciones recursivas y Memoizacion</h3>

Se pueden hacer funciones que se ejecuten así mismas. Muchas veces es necesarios guardar los valores devueltos para evitar que se llame innecesariamente.

let contadorMemo = 1
functionfibonacciMemo(num, memoria = {}) {
  contadorMemo++
  if (memoria[num]) return memoria[num]
  if (num == 1) return0
  if (num == 2) return1

  return memoria[num] = fibonacciMemo(num - 1, memoria) +
            fibonacciMemo(num - 2, memoria)
}

let contadorRec = 1
functionfibonacciRecursivo(num) {
  contadorRec++
  if (num == 1) return0
  if (num == 2) return1

  return fibonacciRecursivo(num - 1) +
      fibonacciRecursivo(num - 2)
}

<h3>Iteradores</h3>

Los iteradores son funciones que preparan un contexto con el fin de devolver valores continuos hasta finalizar.

functionfibonacci(){
  let a=0, b=1//Closure
  return{
    next: function() {
     let f= aa = bb = f + a
     return{ value: f, done: false}
    }
  }
}

const fibo = fibonacci()

fibo.next().value
<h3>Generadores</h3>

Los generadores funcionan como Iteradores. Para definir un Iterador hay que poner un ‘*’ después de la función y un yield en donde se desea devolver un valor y retomar para más tarde. Para continuar un Generador se indica el método next y para finalizar se indica el método return

function* fibonacci(){
  let a=0, b=1//yield a - hace que la siguiente vez que se ejecute // la función continue en la siguiente linea.while (true) {
    let f= a
    a = b
    b = f + a
    let reset = yield f
    if(reset) a=0, b=1
  }
}

const fibo = fibonacci()
// Comandos para la ejecución en la consola
fibo 
fibo.next()
fibo.next(reset)

<h3>Estructuras de Datos Inmutables</h3>

Los datos en javascript suelen guardarse en memoria y podrían ser llamados por error. Esto provocaría que si tengo una variable que se fue asignada con el mismo valor de otra y la modificó, ambas verán reflejadas el mismo cambio.

let item1 = { id: 1, text: "Hola" }
let item2 = item1

item2.id = 2//item1 también tendrá el id en 2

Para prevenir que esto ocurra se puede utilizar distintas formas de asignación conocidas como immutability o inmutabilidad. Una forma de utilizarlo es:

let item1 = { id: 1, text: "Hola" }
let item2 = Object.assing({}, item1)

item2.id = 2

Tambien se puede utilizar una librería hecha por Facebook que controla el tema de inmutabilidad.

https://facebook.github.io/immutable-js/

<h1>NPM</h1>

NPM es un package manager para JavaScript. Eso quiere decir que es un lugar donde están guardadas aquellas librerías o dependencias que usaremos en nuestros proyectos, y de hecho, tu puedes crear y compartir las tuyas.

¿Qué tipo de dependencias?, muchas, tanto de backend y front-end que utilicen JavaScript, quizás unas ya las conoces, las puedes consultar las más populares en:

https://www.npmjs.com/

¿Qué necesito para publicar un módulo de NPM?

Lo primero es tener una cuenta en el sitio, solo necesitas correo y contraseña, lo obtienes en:

https://www.npmjs.com/signup

Lo siguiente es tener instalado Node.js, ya que entre otras cosas, es la plataforma que nos ayuda a tener instaladas las herramientas de NPM en nuestra terminal. Si aún no lo tienes, lo puedes hacer desde:

https://nodejs.org/en/download/

Teniendo cuenta lo anterior, tenemos que decirle a NPM quienes somos, para ello, necesitamos pasar unos datos desde la terminal:

  1. npm set http://init.author.name/ “Tu nombre”

  2. npm set init.author.email “Tu correo”

  3. npm set init.author.url “Una url de tu sitio, inclusive puede ser una red social”

De inmediato ejecutamos npm login y agregaremos las credenciales que obtuvimos en el sitio. Si alguno de nuestros datos no es correcto, se va a mostrar en la terminal.

<h2>Creando nuestro paquete</h2>

Paso 0- Crear un repositorio en GIT.

Paso 1- Dentro de “Terminal” en la carpeta que creamos iniciar escribiendo

npm init

**Escribir: ** Nombre, Versión, Descripción, Entry point (archivo principal, index.js), Git repository (url de nuestro archivo git), Keywords, Licencia “MIT

Paso 2- Crear un nuevo doc. txt llamado “LICENSE” y pegar el siguiente texto de Iniciativa MIT LICENCE,año y propietario.

Paso 3- Crear un nuevo doc. txt llamado README.md, (md significa “markdown”) Youtube video, Readme_md example, Markdown_cheatsheet

Paso 4.- Escribir el código en nuestro paquete y usar BABEL para que sea compatible.

Crear carpeta SRC (código source o fuente). Dentro crear un código JS y pegarle nuestro código (user export default …)

Instalar babel

npm install --save-dev babel-cli

Resultado

{
  "name": "my-project",
  "version": "1.0.0",
  "devDependencies": {
    "babel-cli": "^6.0.0"
  }
}

Para usarlo añadir en los scripts de package.json

 {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "babel src -d lib"
+   },
    "devDependencies": {
      "babel-cli": "^6.0.0"
    }
  }

Donde “src” sera la carpeta de origen y lib será el resultado

Para ejecutar el comando usar

npm run build

Finalmente crear el archivo .babelrc

npm install babel-preset-env --save-dev

{
  "presets": ["env"]
}

Cambiar en el package.json el main por el archivo generado.

Paso 5- Hacer un “Test” con el código sig: **npm install --save-dev mocha chai ** (Utilizar 2 librerías muy comunes: mocha chai)

* Crear carpeta "test" y dentro un archivo llamado test.js.

Después de crear el archivo procedemos a importar chai y el paquete que creamos

const expect = require('chai').expect
const toTest = require('..').default;

Después tendremos que especificar que paquete vamos a testear con describe y dentro del mismo con it indicamos que funcione vamos a testear

describe('#toTest , function () {

it('Si la palabra termina en ar, se quitan esos caracteres', function(){
  const translation = toTest ("text")
  expect(translation).to.equal("a value")
})

Paso 6- Publicarlo en NPM:

Para publicar en NPM subiremos el repositorio en github. Para hacerlo se digita en consola

git init

Esto añadirá git en nuestro proyecto. Para indicar la ruta de github en la que trabaja el proyecto

git remote add origin + "https://github.com/@User/@Repo"

Luego se procede a hacer commit y push al proyecto en github. Y cuando nuestro proyecto ya se encuentra en github procedemos a publicarlo en NPM

npm publish

<h1>Créditos y Cambios</h1>

MoisesMannarino - Aporte y corrección en variables.
Team Platzi - Markdown Rules!

Escribe tu comentario
+ 2