├── .gitignore ├── src ├── es6 │ ├── 08-module.js │ ├── module.js │ ├── 10-set-add.js │ ├── 05-object-literals.js │ ├── 01-arrow-function.js │ ├── 04-default-params.js │ ├── 09-generator.js │ ├── 02-strings.js │ ├── 00-let-const.js │ ├── 06-promises.js │ ├── 04-rest-spread.js │ └── 07-clases.js ├── es7 │ ├── 00-exponential.js │ └── 01-array-includes.js ├── es12 │ ├── 00-numeric-separators.js │ ├── 02-promise-any.js │ ├── 01-replaceall.js │ └── 03-private.js ├── es11 │ ├── module.js │ ├── 04-globalthis.js │ ├── 06-dynamic-import.js │ ├── 00-optional-chaining.js │ ├── 02-nullish.js │ ├── 03-promise-allsettle.js │ ├── 05-matchall.js │ ├── index.html │ └── 01-bigint.js ├── es13 │ ├── 01-top-leve-await.js │ ├── 00-at.js │ └── products.js ├── es8 │ ├── 04-trailing-commas.js │ ├── 03-string-padding.js │ ├── 01-object-values.js │ ├── 00-object-entries.js │ └── 05-async-functions.js ├── es10 │ ├── 01-trimstart-trimend.js │ ├── 03-fromentries.js │ ├── 02-try-catch.js │ └── 00-flat-map.js └── es9 │ ├── 00-regex.js │ ├── 01-spread.js │ ├── 02-finally.js │ └── 04-async.js ├── images ├── logo.png ├── ecma01.PNG ├── screenshot.png ├── 112-book-morph-linealtrans.gif └── OG_crop_16-9-escmascript-historia.png ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/es6/08-module.js: -------------------------------------------------------------------------------- 1 | import hello from "./module.js"; 2 | 3 | hello(); -------------------------------------------------------------------------------- /src/es7/00-exponential.js: -------------------------------------------------------------------------------- 1 | const data = 3 ** 4; 2 | console.log(data) 3 | -------------------------------------------------------------------------------- /src/es12/00-numeric-separators.js: -------------------------------------------------------------------------------- 1 | const value = 100_000_000_000; 2 | console.log(value) 3 | -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferneynava/Curso-de-ECMAScript/HEAD/images/logo.png -------------------------------------------------------------------------------- /images/ecma01.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferneynava/Curso-de-ECMAScript/HEAD/images/ecma01.PNG -------------------------------------------------------------------------------- /src/es11/module.js: -------------------------------------------------------------------------------- 1 | export function hello (nombre) { 2 | console.log('Hola Mundo!' + nombre) 3 | } -------------------------------------------------------------------------------- /images/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferneynava/Curso-de-ECMAScript/HEAD/images/screenshot.png -------------------------------------------------------------------------------- /src/es6/module.js: -------------------------------------------------------------------------------- 1 | const hello = () => { 2 | console.log("Hello!"); 3 | } 4 | 5 | export default hello; -------------------------------------------------------------------------------- /src/es13/01-top-leve-await.js: -------------------------------------------------------------------------------- 1 | import { products } from "./products.js" 2 | 3 | console.log(products) 4 | console.log("Hey!!") -------------------------------------------------------------------------------- /src/es8/04-trailing-commas.js: -------------------------------------------------------------------------------- 1 | const array = [24, 34, 25, 24, , , , , 67]; 2 | 3 | console.log(array); 4 | console.log(array.length); -------------------------------------------------------------------------------- /src/es8/03-string-padding.js: -------------------------------------------------------------------------------- 1 | const string = "Hello" 2 | 3 | console.log(string.padStart(6, "_")); 4 | console.log(string.padEnd(6, "_")); -------------------------------------------------------------------------------- /images/112-book-morph-linealtrans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferneynava/Curso-de-ECMAScript/HEAD/images/112-book-morph-linealtrans.gif -------------------------------------------------------------------------------- /src/es10/01-trimstart-trimend.js: -------------------------------------------------------------------------------- 1 | const hello = " Hello World! "; 2 | console.log(hello.trimStart()); 3 | console.log(hello.trimEnd()); -------------------------------------------------------------------------------- /src/es13/00-at.js: -------------------------------------------------------------------------------- 1 | const array = ["one", "two", "three", "four", "five", "six"] 2 | 3 | console.log(array[array.length -1]) 4 | console.log(array.at(-1)) -------------------------------------------------------------------------------- /images/OG_crop_16-9-escmascript-historia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ferneynava/Curso-de-ECMAScript/HEAD/images/OG_crop_16-9-escmascript-historia.png -------------------------------------------------------------------------------- /src/es10/03-fromentries.js: -------------------------------------------------------------------------------- 1 | const entries = new Map ([["name", "oscar"], ["age", 34]]) 2 | console.log(entries) 3 | console.log(Object.fromEntries(entries)) -------------------------------------------------------------------------------- /src/es11/04-globalthis.js: -------------------------------------------------------------------------------- 1 | console.log(window); // navegador 2 | console.log(global); // node 3 | console.log(selft); // webWorker 4 | console.log(globalThis); -------------------------------------------------------------------------------- /src/es9/00-regex.js: -------------------------------------------------------------------------------- 1 | const regex = /(\d{4})-(\d{2})-(\d{2})/; 2 | const matchers = regex.exec("2022-01-01"); 3 | console.table(matchers); 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/es13/products.js: -------------------------------------------------------------------------------- 1 | import fetch from "node-fetch" 2 | 3 | const response = await fetch("https://api.escuelajs.co/api/v1/products") 4 | const products = await response.json() 5 | 6 | export {products}; -------------------------------------------------------------------------------- /src/es10/02-try-catch.js: -------------------------------------------------------------------------------- 1 | try { 2 | hello() 3 | } catch (error) { 4 | console.log(error) 5 | } 6 | 7 | try { 8 | anotherFn(); 9 | } catch { 10 | console.log("Esto es un error") 11 | } -------------------------------------------------------------------------------- /src/es10/00-flat-map.js: -------------------------------------------------------------------------------- 1 | // flat 2 | const array = [1,1,2,3,4, [1,3,5,6, [1,2,4]]]; 3 | console.log(array.flat(2)); 4 | 5 | // flatmap 6 | const array2 = [1,2,3,4,5]; 7 | console.log(array2.flatMap(v => [v, v * 2])); 8 | 9 | -------------------------------------------------------------------------------- /src/es8/01-object-values.js: -------------------------------------------------------------------------------- 1 | const countries = { MX: "Mexico", 2 | CO: "Colombia", 3 | Cl: "Chile", 4 | PE: "Peru" }; 5 | 6 | console.log(Object.values(countries)); -------------------------------------------------------------------------------- /src/es8/00-object-entries.js: -------------------------------------------------------------------------------- 1 | const countries = { CO: "Colombia", 2 | MX: "Mexico", 3 | CL: "Chile", 4 | PE: "Peru" 5 | }; 6 | 7 | console.log(Object.entries(countries)); -------------------------------------------------------------------------------- /src/es11/06-dynamic-import.js: -------------------------------------------------------------------------------- 1 | const button = document.getElementById("btn") 2 | 3 | button.addEventListener("click", async function () { 4 | const module = await import ("./module.js") 5 | console.log(module) 6 | module.hello(" Ferney Nava"); 7 | }) -------------------------------------------------------------------------------- /src/es6/10-set-add.js: -------------------------------------------------------------------------------- 1 | const list = new Set(); 2 | 3 | list.add("item 1"); 4 | list.add("item 2").add("item 3"); 5 | 6 | console.log(list) 7 | 8 | // Documentacion https://www.digitalocean.com/community/tutorials/understanding-map-and-set-objects-in-javascript-es 9 | -------------------------------------------------------------------------------- /src/es11/00-optional-chaining.js: -------------------------------------------------------------------------------- 1 | const user = { 2 | ferneydev: { 3 | country: 'CO' 4 | }, 5 | Erika: { 6 | country: 'CO' 7 | } 8 | } 9 | 10 | console.log(user.Erika.country); 11 | console.log(user.Erika.age); 12 | console.log(user?.Rector?.country); 13 | 14 | -------------------------------------------------------------------------------- /src/es6/05-object-literals.js: -------------------------------------------------------------------------------- 1 | // enahced object literals 2 | 3 | function newUser(user, age, country, uId) { 4 | return { 5 | user, 6 | age, 7 | country, 8 | id: uId, 9 | } 10 | } 11 | 12 | console.log(newUser("Ferney", 24, "CO", 1)); 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/es11/02-nullish.js: -------------------------------------------------------------------------------- 1 | const anotherNumber = null; 2 | const valiDate = anotherNumber ?? 5; 3 | console.log(valiDate); 4 | 5 | /// OR vs Nullish coalescing 6 | const id = 0 7 | const orId = id || "Sin id" 8 | const nullishId = id ?? "Sin id" 9 | 10 | console.log(orId) // "Sin id" 11 | console.log(nullishId) // 0 -------------------------------------------------------------------------------- /src/es6/01-arrow-function.js: -------------------------------------------------------------------------------- 1 | function square(num){ 2 | return num * num; 3 | } 4 | 5 | const square = (num) => { 6 | return num * num; 7 | } 8 | 9 | const square = num => num * num; //function con el return implicito no hay necesidada de escribir el return 10 | 11 | console.log(square(4)); 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/es12/02-promise-any.js: -------------------------------------------------------------------------------- 1 | const promise1 = new Promise((resolve, reject) => reject("Reject")) 2 | const promise2 = new Promise((resolve, reject) => resolve("Resolve")) 3 | const promise3 = new Promise((resolve, reject) => resolve("Resolve 2")) 4 | 5 | Promise.any([promise1, promise2, promise3]) 6 | .then( reject => console.log(reject)) -------------------------------------------------------------------------------- /src/es11/03-promise-allsettle.js: -------------------------------------------------------------------------------- 1 | const promise1 = new Promise((resolve, reject) => reject("Reject")) 2 | const promise2 = new Promise((resolve, reject) => resolve("Resolve")) 3 | const promise3 = new Promise((resolve, reject) => resolve("Resolve 2")) 4 | 5 | Promise.allSettled([promise1, promise2, promise3]) 6 | .then(response => console.log(response)); -------------------------------------------------------------------------------- /src/es9/01-spread.js: -------------------------------------------------------------------------------- 1 | const user = { 2 | username: "FerneyNava", 3 | age: 26, 4 | country: "CO" 5 | } 6 | const {username,...values} = user; 7 | console.log(username); 8 | console.log(values); 9 | 10 | 11 | const arrays = ["Ferney", 26, "CO"]; 12 | const [names, ...ageCountry] = arrays; 13 | console.log(names, ageCountry) 14 | -------------------------------------------------------------------------------- /src/es11/05-matchall.js: -------------------------------------------------------------------------------- 1 | const regex = /\b(Apple)+\b/g; 2 | const fruit = 'Apple, Banana, Kiwi, Apple, Orange, Apple, etc. etc etc.'; 3 | for (const match of fruit.matchAll(regex)){ 4 | console.log(match) 5 | } 6 | 7 | const regexx = /\b(Apple)+\b/g; 8 | const fruitt = 'Apple, Banana, Kiwi, Apple, Orange, Apple, etc. etc etc.'; 9 | const array = [...fruitt.matchAll(regexx)] 10 | console.log(array[2]) 11 | 12 | -------------------------------------------------------------------------------- /src/es11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Dynamic Import 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/es12/01-replaceall.js: -------------------------------------------------------------------------------- 1 | const string = "JavaScript es un maravilloso lenguaje de programación" 2 | 3 | const replacedString = string.replace("JavaScript", "TypeScript") 4 | console.log(replacedString) 5 | 6 | const mensaje = "JavaScript es maravilloso, con JavaScript puedo crear el futuro de la web." 7 | const newMensaje = mensaje.replaceAll("JavaScript", "Python") 8 | console.log(newMensaje) //Python es maravilloso, con Python puedo crear el futuro de la web. -------------------------------------------------------------------------------- /src/es6/04-default-params.js: -------------------------------------------------------------------------------- 1 | function newUser(name, age, country){ 2 | var name = name || "Ferney"; 3 | var age = age || 24; 4 | var country = country || "Co"; 5 | console.log(name, age, country); 6 | } 7 | 8 | newUser(); 9 | newUser("Camila", 24, "MX"); 10 | 11 | //Es6 12 | 13 | function newAdmin(name = "Ferney", age = 32, country = "CL"){ 14 | console.log(name, age, country); 15 | } 16 | 17 | newAdmin(); 18 | newAdmin("Ana", 28, "PE"); -------------------------------------------------------------------------------- /src/es8/05-async-functions.js: -------------------------------------------------------------------------------- 1 | const fnAsync = () => { 2 | return new Promise((resolve, reject) => { 3 | (true) 4 | ? setTimeout(() => resolve("Async!!"), 2000) 5 | : reject(new Error("Error")); 6 | }) 7 | } 8 | 9 | const anotherFn = async () => { 10 | const something = await fnAsync(); 11 | console.log(something); 12 | console.log("Hello!"); 13 | } 14 | 15 | console.log("Before"); 16 | anotherFn(); 17 | console.log("After"); 18 | 19 | -------------------------------------------------------------------------------- /src/es9/02-finally.js: -------------------------------------------------------------------------------- 1 | const anotherFuncion = () => { 2 | return new Promise((resolve, reject) => { 3 | if(true){ 4 | resolve("Hey!!"); 5 | } else { 6 | reject("Whoooops!") 7 | } 8 | }) 9 | } 10 | anotherFuncion() 11 | .then(response => console.log(response)) //En caso que se ejecute resolve //then 12 | .catch(err => console.log(err)) //En caso que se ejecute reject //catch 13 | .finally(() => console.log("Finnaly")); 14 | 15 | -------------------------------------------------------------------------------- /src/es6/09-generator.js: -------------------------------------------------------------------------------- 1 | let array = ["Oscar", "David", "Ana", "Ulises", "Jennifer"]; 2 | function* iterate(array){ 3 | for(let value of array){ 4 | yield value; 5 | } 6 | } 7 | 8 | const it = iterate(array); 9 | 10 | console.log(it.next().value); 11 | console.log(it.next().value); 12 | console.log(it.next().value); 13 | console.log(it.next().value); 14 | console.log(it.next().value); 15 | console.log(it.next().value); 16 | console.log(it.next().value); 17 | 18 | // Documentacion https://www.digitalocean.com/community/tutorials/understanding-generators-in-javascript-es -------------------------------------------------------------------------------- /src/es6/02-strings.js: -------------------------------------------------------------------------------- 1 | let hello = "Hello"; 2 | let world = "World"; 3 | let epicPhrase = hello + " " + world + "!"; 4 | 5 | // Template literals 6 | let epicPhrase2 = `${hello} ${world}!`; 7 | console.log(epicPhrase2); 8 | 9 | // Multi-line strings 10 | let lorem = "esto es un string \n" + "esto es otra linea"; 11 | 12 | let lorem2 = `Esta es una frase epica 13 | la continuación de esa frase epica. 14 | `; 15 | 16 | console.log(lorem); 17 | console.log(lorem2); 18 | 19 | 20 | let edad = 25 + 1; 21 | let vive = "Zipaquira" 22 | 23 | let ferney = `Ferney tiene ${edad} años y viven en ${vive}`; 24 | console.log(ferney); 25 | 26 | console.log(`Ferney Nava`); 27 | -------------------------------------------------------------------------------- /src/es9/04-async.js: -------------------------------------------------------------------------------- 1 | async function* anotherGenerator() { 2 | yield await Promise.resolve(1); 3 | yield await Promise.resolve(2); 4 | yield await Promise.resolve(3); 5 | } 6 | 7 | const other = anotherGenerator(); 8 | other.next().then(response => console.log(response.value)); 9 | other.next().then(response => console.log(response.value)); 10 | other.next().then(response => console.log(response.value)); 11 | console.log("Hello"); 12 | 13 | async function arrayOfNames(array){ 14 | for await (let value of array){ 15 | console.log(value); 16 | } 17 | } 18 | 19 | const names = arrayOfNames(["Ferney", "Nava", "Trujillo"]); 20 | console.log("After") 21 | -------------------------------------------------------------------------------- /src/es11/01-bigint.js: -------------------------------------------------------------------------------- 1 | const aBigNumber = 899867566537653456456n; 2 | const anotherBigNumber = BigInt(899867566537653456456) 3 | 4 | console.log(aBigNumber) 5 | console.log(anotherBigNumber) 6 | 7 | //Limites númerios en Javascript 8 | const max = Number.MAX_SAFE_INTEGER //Limite de números maximos en JavaScript 9 | const min = Number.MIN_SAFE_INTEGER //Limite de números minimos en JavaScript 10 | 11 | console.log(max) //9007199254740991 12 | console.log(min) //-9007199254740991 13 | 14 | const increment = 2 15 | const number = Number.MAX_SAFE_INTEGER + increment 16 | const bigInt = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(increment) 17 | 18 | console.log(number) //9007199254740992 19 | console.log(bigInt) //9007199254740993n -------------------------------------------------------------------------------- /src/es6/00-let-const.js: -------------------------------------------------------------------------------- 1 | //Acá estamos declarando y asignando el valor 2 | var lastName = "David"; 3 | //Acá reasignamos el valor de la variables lastName 4 | lastName = "Oscar"; 5 | console.log(lastName); 6 | 7 | //Declaramos y asignamos 8 | let fruit = "Apple"; 9 | //Reasignamos el valor de la variable fruit 10 | fruit = "Kiwi"; 11 | console.log(fruit); 12 | 13 | 14 | const animal = "Dog"; 15 | //Con const no podemos reasignar un valor 16 | animal = "Cat"; 17 | console.log(animal); 18 | 19 | //Arrow Functions 20 | const fruits = () => { 21 | if(true){ 22 | var fruit1 = "Apple"; 23 | let fruit2 = "Kiwi"; 24 | const fruit3 = "Banana" 25 | } 26 | console.log(fruit1); //function scope 27 | //console.log(fruit2); //block scope 28 | // console.log(fruit3); //block scope 29 | } 30 | 31 | fruits(); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "curso-ecmascript", 3 | "version": "1.0.0", 4 | "description": "Nuevo Curso de ECMAScript de Platzi ", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/ferneynava/Nuevo-Curso-de-ECMAScript-.git" 12 | }, 13 | "keywords": [ 14 | "javascript", 15 | "ecmascript" 16 | ], 17 | "author": "Ferney Nava ", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/ferneynava/Nuevo-Curso-de-ECMAScript-/issues" 21 | }, 22 | "homepage": "https://github.com/ferneynava/Nuevo-Curso-de-ECMAScript-#readme", 23 | "type": "module", 24 | "dependencies": { 25 | "node-fetch": "^3.3.0" 26 | }, 27 | "devDependencies": { 28 | "standard": "^17.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/es12/03-private.js: -------------------------------------------------------------------------------- 1 | class user { 2 | // constructor 3 | constructor(name, age){ 4 | this.name = name; 5 | this.age = age; 6 | } 7 | 8 | // metodos 9 | #speak (){ 10 | console.log("Puede acceder ") 11 | return "Hello"; 12 | } 13 | 14 | greeting(){ 15 | return `${this.#speak()} ${this.name}`; 16 | 17 | } 18 | 19 | get #uAge() { //get obtener. Obtener el valor de age 20 | return this.age; 21 | 22 | } 23 | 24 | set #uAge(n) { //set asignar. Asignar al age el valor de n 25 | this.age = n 26 | } 27 | 28 | } 29 | 30 | const platzi = new user("Ferney Nava", 26); 31 | platzi.greeting(); 32 | console.log(platzi.uAge); //Undefined no se puede acceder a uAge puesto de que esta privado(#) solo se puede acceder dentro del constructor 33 | console.log(platzi.uAge = 45) 34 | 35 | -------------------------------------------------------------------------------- /src/es6/06-promises.js: -------------------------------------------------------------------------------- 1 | const anotherFuncion = () => { 2 | return new Promise((resolve, reject) => { 3 | if(true){ 4 | resolve("Hey!!"); 5 | } else { 6 | reject("Whoooops!") 7 | } 8 | }) 9 | } 10 | anotherFuncion() 11 | .then(response => console.log(response)) //En caso que se ejecute resolve //then 12 | .catch(err => console.log(err)); //En caso que se ejecute reject //catch 13 | 14 | 15 | 16 | 17 | 18 | const promesa = () => { 19 | return new Promise((resolve, reject) => { 20 | if (something) { 21 | //true o false 22 | resolve("Se ha resuelto la promesa") 23 | } else { 24 | reject("Se ha rechazado la promesa") 25 | } 26 | }) 27 | } 28 | 29 | promesa() 30 | .then(respuesta => console.log(respuesta)) //En caso que se ejecute resolve 31 | .catch(error => console.log(error)) //En caso que se ejecute reject 32 | -------------------------------------------------------------------------------- /src/es6/04-rest-spread.js: -------------------------------------------------------------------------------- 1 | // array destructuring 2 | 3 | let fruits = ["Apple", "Banana"]; 4 | let [a, b] = fruits; 5 | console.log(a, b); // a = Apple b = Banana 6 | console.log(a); // a = Apple 7 | console.log(b); // b = Banana 8 | //console.log(a, fruits[1]); 9 | 10 | // object destructuring 11 | 12 | let user = {username: "Ferney", age: 34}; 13 | let {username, age} = user; 14 | console.log(username, age); 15 | //console.log(username, user.age); 16 | 17 | let user1 = {username1: "Carlos", age1: 34}; 18 | let {username1: as , age1: bs} = user1; 19 | console.log(as, bs); 20 | 21 | //spread operator 22 | 23 | let person = {name: "Ferney", age: 28} 24 | let country = "CO"; 25 | let data = {id: 1,...person, country}; 26 | console.log(data); 27 | 28 | let numeros = [1,2,4,5,99]; 29 | let array = [...numeros]; 30 | array[0] = 777; 31 | console.log(array); 32 | console.log(numeros); 33 | 34 | // rest 35 | 36 | function sum(num, ...values){ 37 | console.log(values); 38 | console.log(num + values[0]); 39 | return num + values[0]; 40 | } 41 | 42 | sum(1,1,2,3); -------------------------------------------------------------------------------- /src/es6/07-clases.js: -------------------------------------------------------------------------------- 1 | // declarando 2 | class User {} 3 | // instancia de una clase 4 | //const newUser = new User(); 5 | 6 | class user { 7 | //metodos 8 | greeting(){ 9 | return "Hello"; 10 | } 11 | } 12 | 13 | const saludo = new user(); 14 | console.log(saludo.greeting()); 15 | 16 | const herencia = new user(); 17 | console.log(herencia.greeting()); 18 | 19 | // constructor 20 | 21 | class user { 22 | // Constructor 23 | constructor(){ 24 | console.log("Nuevo Usuario") 25 | } 26 | greeting(){ 27 | return "Hello"; 28 | } 29 | } 30 | 31 | const david = new user(); 32 | 33 | // this 34 | 35 | class user { 36 | constructor(name){ 37 | this.name = name 38 | } 39 | // metodos 40 | speak(){ 41 | return "Hello" 42 | } 43 | 44 | greeting(){ 45 | return `${this.speak()} ${this.name}`; 46 | } 47 | } 48 | 49 | const ferney = new user("Nava"); 50 | console.log(ferney.greeting()); 51 | 52 | // setters getters 53 | 54 | class user { 55 | // constructor 56 | constructor(name, age){ 57 | this.name = name; 58 | this.age = age; 59 | } 60 | 61 | // metodos 62 | speak (){ 63 | return "Hello"; 64 | } 65 | 66 | greeting(){ 67 | return `${this.speak()} ${this.name}`; 68 | } 69 | 70 | get uAge() { //get obtener. Obtener el valor de age 71 | return this.age; 72 | } 73 | 74 | set uAge(n) { //set asignar. Asignar al age el valor de n 75 | this.age = n; 76 | } 77 | } 78 | 79 | const platzi = new user("Ferney Nava", 26); 80 | console.log(platzi.uAge); 81 | console.log(platzi.uAge = 20); -------------------------------------------------------------------------------- /src/es7/01-array-includes.js: -------------------------------------------------------------------------------- 1 | let numbers = [1, 3, 4, 6, 8]; 2 | 3 | console.log(numbers.includes(4)); //True se encuentra en el array 4 | console.log(numbers.includes(9)); //false no se encuentra en el array 5 | 6 | const list = ["Oscar", "David", "Ana"]; 7 | 8 | console.log(list.includes("David")); //True se encuentra en el array 9 | console.log(list.includes("david")); //False no se encuentra en el array por pero david en el array esta la primera letra en mayuscula 10 | 11 | // Índices positivos y negativos 12 | // Los indicies positivos comienzan desde el 0 hasta la longitud total menos uno, de izquierda a derercha del array 13 | // [0,1,2,3,4,5,....,lenght-1] 14 | // Los indices negativos comienzan desde -1 hasta el negativo de la longitd total del array, de derecha a izquierda 15 | // [-lenght,...,-3,-2,-1] 16 | 17 | // Uilizando arrays 18 | let frutas = ["manzana", "pera", "piña", "uva"] 19 | 20 | console.log(frutas.includes("manzana")); //True se encuentra en el array 21 | console.log(frutas.includes("Pera")); // Flase no se encuentra en el array 22 | console.log(frutas.includes("sandía")); // False no se encuentra en el array 23 | console.log(frutas.includes("manzana", 1)); // False no encuentra en el array por que manzana se encuentra es en el indice 0 24 | console.log(frutas.includes("piña", -1)); // False no encuentra en el array por que piña se encuentra es en el indice -2 25 | console.log(frutas[0].includes("man")); //True evalua solo el elemento que se encuentra en el indice 0 y manzana si tiene las letras man 26 | 27 | // Utilizando string 28 | 29 | const saludo = "Hola mundo" 30 | 31 | console.log(saludo.includes("Hola")); // true se encuentra en el string 32 | console.log(saludo.includes("Mundo")); // false no se encuentra en el string 33 | console.log(saludo.includes(" ")); // true se encuentra en el string 34 | console.log(saludo.includes("Hola", 1)) // false no se encuentra en el string 35 | console.log(saludo.includes("mundo", -5)) // true se encuentra en el string 36 | 37 | /// objetos 38 | // En objetos tambien existen formas para saber si existe una propiedad 39 | //Evalua solo las clases de los objetos 40 | // - La palabra reservada in 41 | // - El metodo de objetos hasOwnProperty 42 | // - El metodo Object.hasOwm, que recibe el objeto y la propìedad a evaluar 43 | 44 | const letras = { 45 | a: 1, 46 | b: 2, 47 | c: 3, 48 | } 49 | 50 | console.log("a" in letras); //true en el objeto se encuentra la clave "a" 51 | console.log(letras.hasOwnProperty("a")); //true en el objeto se encuentra la clave "a" 52 | console.log(Object.hasOwn(letras, "a")); //true en el objeto se encuentra la clave "a" 53 | 54 | // in evalua todas las propiedades del objeto y del prototipo 55 | // El metodo hasOwnProperty evalúa solamente las propiedades del objeto. 56 | 57 | const letrass = {d: 4, e: 5, f: 7} 58 | 59 | console.log(letrass) 60 | console.log(letrass.hasOwnProperty("toString")); //false 61 | 62 | console.log("toString" in letrass) //true por el objeto letrass tiene un prototipo que se llama toString 63 | console.log(Object.hasOwn(letrass, "toString")); //false 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [![Contributors][contributors-shield]][contributors-url] 4 | [![Forks][forks-shield]][forks-url] 5 | [![Stargazers][stars-shield]][stars-url] 6 | [![Issues][issues-shield]][issues-url] 7 | [![MIT License][license-shield]][license-url] 8 | [![LinkedIn][linkedin-shield]][linkedin-url] 9 | 10 | 11 |
12 |
13 | 14 | Logo 15 | 16 | 17 |

Curso de ECMAScript: Historia y Versiones de JavaScript

18 | 19 |

20 | JavaScript es el lenguaje más utilizado para desarrollo de aplicaciones web, principalmente en el frontend. Cada año, ECMA International publica una nueva edición de ECMAScript, la especificación a la cual se ajusta JavaScript. Aprende las nuevas características que implementa ECMAScript desde la versión ES6 hasta la versión ES13 21 |
22 | Explore los documentos » 23 |
24 |

25 |
26 | 27 | --- 28 | 29 | ## Índice 30 | 31 | - [Índice](#índice) 32 | - [Introducción](#introducción) 33 | - [Historia de JavaScript: ¿Qué es ECMAScript?](#historia-de-javascript-¿qué-es-ecmascript) 34 | - [¿Qué es el TC39?](#¿qué-es-el-tc39) 35 | - [ECMAScript 6 (ES6 o ES2015)](#ecmascript-6-es6-o-es2015) 36 | - [Let y const, y arrow function](#let-y-const-y-arrow-function) 37 | - [Strings](#strings) 38 | - [Parámetros por defecto](#parámetros-por-defecto) 39 | - [Asignación de desestructuración](#asignación-de-desestructuración) 40 | - [Spread operator](#spread-operator) 41 | - [Object literals](#object-literals) 42 | - [Promesas](#promesas) 43 | - [Clases](#clases) 44 | - [Module](#module) 45 | - [Generator](#generator) 46 | - [Set-add](#set-add) 47 | - [ECMAScript 7 (ES7 o ES2016)](#ecmascript-7-es7-o-es2016) 48 | - [Operador de potenciación y array includes](#operador-de-potenciación-y-array-includes) 49 | - [ECMAScript 8 (ES8 o ES2017)](#ecmascript-8-es8-o-es2017) 50 | - [Object entries y object values](#object-entries-y-object-values) 51 | - [String padding y trailing commas](#string-padding-y-trailing-commas) 52 | - [Funciones asíncronas](#funciones-asíncronas) 53 | - [ECMAScript 9 (ES9 o ES2018)](#ecmascript-9-es9-o-es2018) 54 | - [Expresiones regulares](#expresiones-regulares) 55 | - [Promise.finally](#promisefinally) 56 | - [ECMAScript 10 (ES10 o ES2019)](#ecmascript-10-es10-o-es2019) 57 | - [Flat-map y trimStart-trimEnd](#flat-map-y-trimstart-trimend) 58 | - [Try catch y fromEntries](#try-catch-y-fromentries) 59 | - [ECMAScript 11 (ES11 o ES2020)](#ecmascript-11-es11-o-es2020) 60 | - [Optional chaining](#optional-chaining) 61 | - [BigInt y Nullish](#bigint-y-nullish) 62 | - [Promise.allSettled ](#promiseallsettled) 63 | - [GlobalThis y matchAll](#globalthis-y-matchall) 64 | - [Dynamic Import](#dynamic-import) 65 | - [ECMAScript 12 (ES12 o ES2021)](#ecmascript-12-es12-o-es2021) 66 | - [Numeric-separators y replaceAll](#numeric-separators-y-replaceall) 67 | - [Promise-any y métodos privados](#promise-any-y-métodos-privados) 68 | - [ECMAScript 13 (ES13 o ES2022)](#ecmascript-13-es13-o-es2022) 69 | - [At](#at) 70 | - [Top level await en el consumo de una API](#top-level-await-en-el-consumo-de-una-api) 71 | - [Contribuyendo](#contribuyendo) 72 | - [Contacto](#contacto) 73 | - [Expresiones de gratitud](#expresiones-de-gratitud) 74 | 75 |

(volvel arriba)

76 | 77 | --- 78 | ### Introducción 79 | 80 | #### Historia de JavaScript: ¿Qué es ECMAScript? 81 | 82 | **ECMAScript es el estándar que en la actualidad se encarga de regir como debe ser interpretado y funcionar el lenguaje JavaScript, a través de una serie de versiones que añaden funcionalidades nuevas.** 83 | 84 | *El primer navegador web:* 85 | - 1950: Inicio de las computadoras, surgen para analizar temas de la segunda guerra mundial. 86 | 87 | - 1969: Se creo la red ARPANET una forma de comunicar dos computadoras, para compartir información. 88 | 89 | - 1990: Tim Berners-lee Invento la World Wide Web las bases de la web. 90 | 91 | - 1993: Nacimiento de Mosaic primer navegador Web. 92 | 93 | - 1994: Marc Andreessen y James H. Clark fundaron Netscape Communications Corporation el primer navegador comercial y que inicio una revolución de la información. 94 | 95 | Entre 1995 y 2001, se enfrentaron Netscape y Microsoft para lograr posicionar comercialmente su propio navegador. Quizás Netscape fue el gran perdedor en las guerras de los navegadores es una de las historias más apasionantes de la crónica de la Red. 96 | 97 | - 1995: Internet Explorer primer navegador web creador por Microsoft. **Mocha** es un lenguaje de programación propuesta creada por Netscape, poco después sería nombrado **LiveScript** y finalmente JavaScript. **JScript** es un lenguaje de programación para la web propuesta creada por Microsoft. 98 | 99 | - 1996: CSS propuesta de estilos creado por Microsoft. 100 | 101 | - 1997: ECMA (*European Computer Manufacturer Association*) estandarizar múltiples lenguajes de programación surgido por parte de Netscape, Microsoft y otras empresas. 102 | 103 | *Evolución de ECMAScript* 104 | 105 | 106 | 107 |

(⬆ Volver a índice)

108 | 109 | --- 110 | #### ¿Qué es el TC39? 111 | 112 | **TC39 grupo de desarrolladores, académicos encargados de revisar y actualizar cada nueva propuesta o funcionalidades, bajo el mando de ECMA. El estándar se caracteriza por una serie de pasos que cada propuesta sigue para publicar en alguna versión de ECMAScript** 113 | 114 | *Etapas de una nueva propuesta para ECMAScript* 115 | 116 | - Stage0: Strawperson (borrador, cualquier persona puede tener una idea para implementar en el estándar). 117 | 118 | - Stage1: Proposal (propuesta formal). 119 | 120 | - Stage2: Draft (borrador, como va a funcionar la implementación el impacto entre otros). 121 | 122 | - Stage3: Candidate (se elige el candidato, vamos a tener una propuesta que va ayudar a mejorar el lenguaje). 123 | 124 | - Stage4: Finished (va a ser desplegada en la versión normalmente en JUNIO). 125 | 126 |

(⬆ Volver a índice)

127 | 128 | --- 129 | ### ECMAScript 6 (ES6 o ES2015) 130 | 131 | #### Let y const, y arrow function 132 | 133 | **Nueva forma para declarar variables let y const** 134 | 135 | Las palabras reservadas **let** y **const** solucionan algunos problemas de **var** tales como el *scope*, *hoisting*, *variables globales*, *re-declaración* y *re-asignación* de variables 136 | 137 | *Variables re-declaradas y re-asignadas* 138 | 139 | La re-declaración consiste en volver a declarar una variable, y la re-asignación es volver a asignar un valor a la variable. Cada palabra reservada (*var, let y const*) tiene una forma diferente de utilizar variables. 140 | 141 | - var: Puede ser re-declarada y re-asignada. 142 | - let: No se puede re-declarada pero si re-asignada. 143 | - const: No se puede re-declarada, ni re-asignada. 144 | 145 | Al momento de re-declarar una variable con let y const, este producirá un error "variable ya declarada" 146 | 147 | **Ejemplo de declaración y asignación en diferentes líneas** 148 | 149 | ```js 150 | // Declaración de variables 151 | var nombreVar 152 | let nombreLet 153 | 154 | // Asignación de variables 155 | nombreVar = "Soy Var" 156 | nombreLet = "Soy Let" 157 | ``` 158 | 159 | **Ejemplo de declarar y asignar con const de diferentes líneas de código** 160 | 161 | ```js 162 | const valorPi 163 | valorPi = 3.14 164 | ``` 165 | 166 | **Ejemplo de re-declaración de variables** 167 | 168 | ```js 169 | var nombreVar = "Soy var" 170 | let nombreLet = "Soy let" 171 | const nombreConst = "Soy const" 172 | 173 | 174 | // Re-declaración de variables 175 | var nombreVar = "var" 176 | console.log(nombreVar) // "var" 177 | 178 | let nombreLet = "let" // SyntaxError: Identifier 'nombreLet' has already been declared. 179 | 180 | const nombreConst = "const" //SyntaxError: Identifier 'nombreConst' has already been declared. 181 | ``` 182 | **Ejemplo de re-asignación de variables** 183 | 184 | ```js 185 | var nombreVar = "Soy var" 186 | let nombreLet = "Soy let" 187 | const nombreConst = "Soy const" 188 | 189 | // Re-asignación de variables 190 | nombreVar = "otro var" 191 | console.log(nombreVar) // "otro var" 192 | 193 | nombreLet = "otro let" 194 | console.log(nombreLet) // "otro let" 195 | 196 | nombreConst = "Otro const" // TypeError: Assignment to constant variable. 197 | ``` 198 | 199 |

(⬆ Volver a índice)

200 | 201 | *Funciones flecha (arrow functions)* 202 | 203 | Consiste en una función anónima. Las funciones anónimas permite no asignarle a un nombre a un conjunto de instrucciones que deseamos ejecutarlo sin necesidad de asociarlo. 204 | 205 | ```js 206 | // Función tradicional 207 | 208 | function nombre (parámetros) { 209 | return valorRetornado 210 | } 211 | 212 | // Función flecha 213 | 214 | const nombre = (parámetros) => { 215 | return valorRetornado 216 | } 217 | ``` 218 | 219 | *Omitir paréntesis en las funciones flecha* 220 | 221 | Si en la función existe un solo parámetro, puede omitir los paréntesis. 222 | 223 | ```js 224 | const multiplicaciónPorDos = num => { 225 | return num * 2 226 | } 227 | ``` 228 | 229 | *Retorno implícito* 230 | 231 | Las funciones flecha tienen un retorno implícito, es decir, se puede omitir la palabra reservada **return**, esto con el fin de que el código sea escrito en una sola línea. 232 | 233 | ```js 234 | // Función tradicional 235 | function suma (num1, num2) { 236 | return num1 + num2 237 | } 238 | 239 | // Función flecha 240 | const suma = (num1, num2) => num1 + num2 241 | ``` 242 | 243 | Si se requiere de más líneas y desea utilizarlo de una manera implícita, deberás envolver el cuerpo de la función entre paréntesis. 244 | 245 | ```js 246 | const suma = (num1, num2) => ( 247 | num1 + num2 248 | ) 249 | ``` 250 | 251 |

(⬆ Volver a índice)

252 | 253 | --- 254 | 255 | #### Strings 256 | 257 | *Concatenación de caracteres* 258 | 259 | Para crear una cadena larga, se puede utilizar la concatenación. Consiste en unir uno o varios caracteres,utilizando el signo de suma. 260 | 261 | ```js 262 | var nombre = "Ferney" 263 | var edad = 26 264 | var mensaje = "Mi nombre es " + nombre " y tengo " + edad + " años." 265 | 266 | console.log(mensaje) // "Mi nombre es Ferney y tengo 26 años." 267 | ``` 268 | 269 | *Cómo utilizar las plantillas literales* 270 | 271 | Se emplea el carácter acento grave (`) y para incluir las variables se utiliza la sintaxis ```${variable}``` 272 | 273 | ```js 274 | var nombre = "Ferney" 275 | var edad = 26 276 | 277 | var mensaje = `Mi nombre es ${nombre} y tengo ${edad} años.` 278 | console.log(mensaje) // "Mi nombre es Ferney y tengo 26 años." 279 | ``` 280 | 281 | *Plantilla multilínea* 282 | 283 | Consiste en crear mensajes que contengan varias líneas separadas entre si, utilizando las plantillas literales. Antes la forma de crear una plantilla multilínea es agregando \n al string. 284 | 285 | ```js 286 | var mensaje = "Línea 1 \n" + "línea 2" 287 | 288 | console.log(mensaje) 289 | // 'Línea 1 290 | // línea 2' 291 | ``` 292 | 293 | Con ES6 solo se necesita utilizar las plantillas literales 294 | 295 | ```js 296 | var mensaje = `Línea 1 297 | línea 2` 298 | 299 | console.log(mensaje) 300 | // 'Línea 1 301 | // línea 2' 302 | ``` 303 |

(⬆ Volver a índice)

304 | 305 | --- 306 | 307 | #### Parámetros por defecto 308 | 309 | Ayudan a definir un valor inicial a las variables que son recibidas en la función. Esto permite mejorar la legibilidad y el mantenimiento del código. 310 | 311 | ```js 312 | // Antes de ES6 se utilizaba los valores por defecto de la siguiente forma. 313 | function newUser(name, age, country){ 314 | var name = name || "Ferney"; 315 | var age = age || 24; 316 | var country = country || "Co"; 317 | console.log(name, age, country); 318 | } 319 | 320 | newUser(); 321 | newUser("Camila", 24, "MX"); 322 | 323 | //Ahora con Es6 se utiliza de esta forma 324 | 325 | function newAdmin(name = "Ferney", age = 32, country = "CL"){ 326 | console.log(name, age, country); 327 | } 328 | 329 | newAdmin(); 330 | newAdmin("Ana", 28, "PE"); 331 | ``` 332 | 333 | *Posición de los parámetros por defecto* 334 | 335 | Si Obligatoriamente necesitas el valor como argumento, es necesario que los parámetros por defecto siempre deben estar en las posiciones finales. 336 | 337 | ```js 338 | function sumar (number1, number2 = 0){...} 339 | sumar(3) 340 | ``` 341 | 342 |

(⬆ Volver a índice)

343 | 344 | --- 345 | #### Asignación de desestructuración 346 | 347 | Es una expresión que consiste en extraer los valores de arrays o propiedades de objetos en distintas variables. 348 | 349 | *Desestructuración de objetos* 350 | 351 | Consiste en extraer las propiedades de un objeto en variables. Por medio del mismo nombre de la propiedad del objeto. 352 | 353 | ```js 354 | const objeto = { 355 | prop1: "valor1", 356 | prop2: "valor2", 357 | ... 358 | } 359 | 360 | // Desestructuración 361 | const { prop1, prop2} = objeto 362 | ``` 363 | 364 | Antes de ES6, se necesitaba acceder al objeto con la notación punto o corchetes por cada propiedad que se necesita y asignar ese valor a una variable diferente. 365 | 366 | ```js 367 | var usuario = { nombre: "FerneyNava", edad: 26, plataforma: "Platzi" } 368 | 369 | var nombre = usuario.nombre 370 | var edad = usuario.edad 371 | var plataforma = usuario["plataforma"] 372 | 373 | console.log(nombre) // "FerneyNava" 374 | console.log(edad) // 26 375 | console.log(plataforma) // "Platzi" 376 | ``` 377 | 378 | Gracias a desestructuración de objetos podemos realizar lo mismo, pero en una sola línea, logrando que el código sea más legible y mantenible 379 | 380 | ```js 381 | const usuario = { nombre: "FerneyNava", edad: 26, plataforma: "Platzi" } 382 | const { nombre, edad, plataforma } = usuario 383 | 384 | console.log(nombre) //"FerneyNava" 385 | console.log(edad) // 26 386 | console.log(plataforma) // "Platzi 387 | ``` 388 | 389 | *Cambiar el nombre de las variables con desestructuración* 390 | 391 | Para cambiar los nombres de las propiedades del objeto, podemos utilizar la desestructuración de la siguiente forma: 392 | 393 | ```js 394 | const objeto = { prop1: "valor1", prop2: "valor2", ... } 395 | 396 | // Desestrcuturación 397 | const { prop1: newProp1, prop2: newProp2 } = objeto 398 | ``` 399 | 400 | **Ejemplo** 401 | 402 | ```js 403 | const usuario = { nombre: "Ferney", edad: "26", plataforma: "Platzi"} 404 | 405 | const { nombre: name, edad: age, plataforma: platform } = usuario 406 | 407 | console.log(name) // "Ferney" 408 | console.log(age) // 26 409 | console.log(platform) // "Platzi" 410 | 411 | console.log(nombre) // Uncaught ReferenceError: nombre is not defined 412 | ``` 413 | 414 | *Desestructuración en parámetros de una función* 415 | 416 | Al enviar un objeto como argumento en la invocación a la declaración de una función, puedes utilizar la desestructuración en los parámetros para obtener los valores diferentes. Hay que tener en cuenta que el nombre debe ser igual a la propiedad del objeto. 417 | 418 | ```js 419 | const usuario = { nombre: "Ferney", edad: "26", plataforma: "Platzi"} 420 | 421 | function datos( { nombre, edad, plataforma }){ 422 | console.log(nombre, edad, plataforma) 423 | } 424 | 425 | datos(usuario) // "Ferney", 23, "Platzi" 426 | ``` 427 | 428 | *Desestructuración de arrays* 429 | 430 | Consiste en extraer los valores de un array en variables, haciendo uso de las posiciones del array. 431 | 432 | ```js 433 | const array = [ 1, 2, 3, 4, 5] 434 | 435 | // Desestructuración 436 | const [ uno, dos, tres ] = array 437 | 438 | console.log(uno) // 1 439 | console.log(dos) // 2 440 | console.log(tres) // 3 441 | ``` 442 | 443 | *Desestructuración para valores retornados de una función* 444 | 445 | En el momento en que una función retorna un array, puedes guardarlo en una variable. Por ende, se puede utilizar la desestructuración para utilizar esos valores por separado de manera legible. 446 | 447 | En el siguiente ejemplo, la función **useState** retorna un array con dos elementos: un valor y otra función actualizada. 448 | 449 | ```js 450 | function useState(value){ 451 | return [value, updateValue()] 452 | } 453 | 454 | //Sin desestructuración 455 | const estado = useState(3) 456 | const valor = estado[0] 457 | const actualizador = estado[1] 458 | 459 | //Con desestructuración 460 | const [valor, actualizador] = useState(3) 461 | ``` 462 |

(⬆ Volver a índice)

463 | 464 | --- 465 | 466 | #### Spread operator 467 | 468 | Consiste en propagar los elementos de un iterable, ya sea un array o string utilizando tres puntos ( ... ) dentro de un array. 469 | 470 | ```js 471 | // Para Strings 472 | const array = [..."Ferney"] // [ "F", "e", "r", "n", "e", "y"] 473 | 474 | // En arrays 475 | const otherArray = [...array] // [ "F", "e", "r", "n", "e", "y"] 476 | ``` 477 | 478 | *Copiar arrays utilizando el operador de propagación* 479 | 480 | Realizar una copia de un array, tendrás que tener cuidado de la referencia en memoria. Los arrays se guardan en una referencia en la memoria del computador, al crear una copia, este tendrá la misma referencia que el original. Por este motivo si cambias algo en la copia, también lo harás en el original. 481 | 482 | ```js 483 | const originalArray = [1,2,3,4,5] 484 | const copyArray = originalArray 485 | copyArray[0] = 0 486 | 487 | originalArray // [0,2,3,4,5] 488 | originalArray === copyArray // true 489 | ``` 490 | 491 | Para lograr evitar esto, utiliza el operador de propagación para crear una copia del array que utilice una referencia en memoria diferente al original. 492 | 493 | ```js 494 | const originalArray = [1,2,3,4,5] 495 | const copyArray = [...originalArray] 496 | copyArray[0] = 0 497 | 498 | originalArray // [1,2,3,4,5] 499 | copyArray // [0,2,3,4,5] 500 | originalArray === copyArray //false 501 | ``` 502 | 503 | *Arrays y añadir elementos con el operador de propagación* 504 | 505 | Para unir dos arrays con el operador de propagación, debes separarlos por comas en un array. 506 | 507 | ```js 508 | const array1 = [1,2,3] 509 | const number = 4 510 | const array2 = [5,6,7] 511 | 512 | const otherArray = [...array1, number, ...array2] 513 | 514 | otherArray // [1,2,3,4,5,6,7] 515 | ``` 516 | 517 | *Cuidado con la copia en diferentes niveles de profundidad arrays* 518 | 519 | El operador de propagación sirve para producir una copia en un solo nivel de profundidad, si existen arrays dentro del array a copiar. Entonces los sub-elementos en cada nivel, tendrán la misma referencia de memoria en la copia y en el original. 520 | 521 | ```js 522 | const originalArray = [1, [2,3], 4,5] 523 | const copyArray = [...originalArray] 524 | 525 | originalArray[1] === copyArray[1] // true 526 | ``` 527 | 528 | *Propiedades de propagación en un objeto* 529 | 530 | Consiste en expandir las propiedades de un objeto utilizando el [spread operator](#spread-operator). Funciona para crear nuevos objetos a partir de otros. 531 | 532 | ```js 533 | const objeto = { 534 | nombre: "Ferney", 535 | age: 26, 536 | } 537 | 538 | const usuario = { 539 | ...objeto, 540 | plataforma: "Platzi" 541 | } 542 | ``` 543 | 544 | *Crear copias de objetos utilizando las propiedades de propagación* 545 | 546 | Semejante a crear copias de *arrays* utilizando el operador de propagación, se puede realizar copias de objetos en un solo nivel mediante las propiedades de propagación. 547 | 548 | Logrando que el segundo objeto tenga referencia en memoria diferente al original. 549 | 550 | ```js 551 | const objetoOriginal = {a: 1, b: 2} 552 | const objetoReferencia = objetoOriginal 553 | const objetoCopia = {...objetoOriginal} 554 | 555 | objetoReferencia === objetoOriginal // true 556 | objetoOriginal === objetoCopia // false 557 | ``` 558 | 559 | *Cuidado con la copia en diferentes niveles de profundidad objetos* 560 | 561 | El operador de propagación sirve para crear una copia en un solo nivel de profundidad, si existen objetos dentro de un objeto a copiar. Entonces los sub-elementos en cada nivel, tendrán la misma referencia en el copia y en el original. 562 | 563 | ```js 564 | const original = {datos: [1, [2, 3], 4, 5]} 565 | const copia = {...original} 566 | 567 | original === copia // false 568 | original["datos"] === copia["datos"] // true 569 | ``` 570 | 571 | Recientemente salió una forma de producir una copia profunda con **StructuredCole**, es una característica reciente. Como es una característica reciente tiene un soporte en navegadores de un 87.71% 572 | 573 | ```js 574 | // Array 575 | const originalArray = [1, [2,3], 4,5] 576 | const copyArray = structuredClone(originalArray) 577 | 578 | originalArray === copyArray // false 579 | originalArray[1] === copyArray[1] //false 580 | 581 | // Objeto 582 | const original = {datos: [1, [2, 3], 4, 5]} 583 | const copia = structuredClone(original) 584 | 585 | original === copia // false 586 | original["datos"] === copia["datos"] // false 587 | ``` 588 | 589 | **Recurso articulo escrito por [midudev](https://midu.dev/como-clonar-un-array-en-javascript/) Cómo clonar un Array en JavaScript de forma correcta y sin problema** 590 | 591 | *Parámetro rest* 592 | 593 | Consiste en agrupar el residuo de elementos mediante la sintaxis de tres puntos ( ... ) seguido de una variable que contendrá los elementos en un array. Sirve para crear funciones que acepten cualquier número de argumentos para agruparlos en un array. 594 | 595 | ```js 596 | function hola (primero, segundo, ...resto){ 597 | console.log(primero, segundo) // 1 2 598 | console.log(resto) // [3,4,5,6] 599 | } 600 | 601 | hola(1,2,3,4,5) 602 | ``` 603 | 604 | También sirve para obtener los elementos restantes de un array u objeto usando desestructuración. 605 | 606 | ```js 607 | const objeto = { 608 | nombre: "Ferney", 609 | age: 26, 610 | plataforma: "Platzi" 611 | } 612 | 613 | const array = [0,1,2,3,4,5] 614 | 615 | const {plataforma, ...usuario} = objeto 616 | const [cero, ...positivos] = array 617 | 618 | usuario // { nombre: "Andres", age: 23 } 619 | positivos // [1, 2, 3, 4, 5] 620 | ``` 621 | 622 | Es importe que el parámetro rest siempre debe estar en la ultima posición de los parámetros de la función, puesto de que existirá un error de sintaxis. 623 | 624 | ```js 625 | function hola (primero, ...rest, ultimo){ ... } 626 | // SyntaxError: Rest element must be last element. 627 | ``` 628 | 629 | *Rest vs operador de propagación* 630 | 631 | El parámetro rest agrupa el residuo de elementos y siempre debe estar en la última posición, el operador de propagación expande los elementos de un iterable en un array y no importa en que lugar esté situado. 632 | 633 | ```js 634 | const array = [1,2,3,4,5] 635 | 636 | function hola (primero, segundo, ...resto) { // <- Parámetro Rest 637 | console.log(primero, segundo) // 1 2 638 | console.log(resto) // [3,4,5, "final"] 639 | } 640 | 641 | hola(...array, "final") //<- Operador de propagación 642 | //Lo mismo que hacer -> hola(1,2,3,4,5, "final") 643 | ``` 644 | 645 | 646 |

(⬆ Volver a índice)

647 | 648 | --- 649 | 650 | #### Object literals 651 | 652 | Consiste en crear objetos a partir de variables sin repetir el nombre. Anteriormente para crear un objeto a partir de variables consistía en la siguiente manera: 653 | 654 | ```js 655 | const nombre = "Ferney" 656 | const edad = 23 657 | 658 | const objeto = { 659 | nombre: nombre 660 | edad: edad 661 | } 662 | 663 | objeto // { nombre: 'Andres', edad: 23 } 664 | ``` 665 | 666 | *Cómo utilizar objetos literales* 667 | 668 | Gracias a los parámetros de objeto puedes obviar la repetición de nombre,JavaScript creará la propiedad a partir del nombre de la variable con su respectivo valor. 669 | 670 | ```js 671 | const nombre = "Ferney" 672 | const edad = 26 673 | 674 | const objeto = {nombre, edad} 675 | 676 | objeto // { nombre: "Andres", edad: 23 } 677 | ``` 678 | 679 | El resultado es el mismo, pero sin la necesidad de repetir palabras. Se puede combinar con variables que su propiedad tiene un nombre diferente. 680 | 681 | ```js 682 | const nombre = "Ferney" 683 | const edad = 26 684 | const esteEsUnID = 1 685 | 686 | const objeto = { 687 | nombre, 688 | edad, 689 | id: esteEsUnID 690 | } 691 | 692 | objeto // { nombre: 'Andres', edad: 23, id: 1 } 693 | ``` 694 | 695 |

(⬆ Volver a índice)

696 | 697 | --- 698 | 699 | #### Promesas 700 | 701 | Las promesas es una forma de manejar el asincronismo en JavaScript y se representa como un objeto que puede generar un valor único a futuro, tiene dos estados, o esta resuelta o incluye una razón por la cual no ha sido resuelta la solución. 702 | 703 | *Cómo utilizar las promesas* 704 | 705 | La clase **Promise** y sus métodos **then** y **catch** fueron añadidos en ES6. Esto logra resolver un problema del manejo del asincronismo con *callbacks*, llamado *Callback Hell* 706 | 707 | La clases **Promise** es una función que recibe dos parámetros: 708 | 709 | - *resolve*: cuando la promesa es resulta. 710 | - *reject*: cuando la promesa es rechazada. 711 | 712 | No es necesario utilizar como nombres estos dos parámetros, puedes utilizar cualquier nombre. 713 | 714 | ```js 715 | const promesa = () => { 716 | return new Promise((resolver, reject) => { 717 | if(something) { 718 | //true o false 719 | resolver("Se ha resuelto la promesa") 720 | } else { 721 | reject("Se ha rechazado la promesa") 722 | } 723 | }) 724 | } 725 | 726 | promesa() 727 | .then(respuesta => console.log(respuesta)) // En caso que se ejecute resolve 728 | .catch(error => console.log(error)) // En caso que se ejecute reject 729 | ``` 730 | 731 |

(⬆ Volver a índice)

732 | 733 | --- 734 | 735 | #### Clases 736 | 737 | Class es una forma para crear clases y manejar la herencia, logrando resolver problemas con el paradigma de programación orientado a objetos. 738 | 739 | *Estructura de las clases en JavaScript* 740 | 741 | La estructura de clases en JavaScript consiste en: 742 | 743 | - Definir la clase con la palabra reservada class, seguido del nombre. 744 | 745 | - La función constructora sirve para crear las variables necesarias en la instancia del objeto, a partir de los argumentos en la instancia. 746 | 747 | - Para definir atributos necesitas el contexto this, que representa la instancia del objeto. 748 | 749 | - Métodos para definir las acciones de las clases. 750 | 751 | - Para crear una instancia, deberás declarar una variable e invocar la clase con la palabra reservada new. 752 | 753 | ```js 754 | class user { 755 | // constructor 756 | constructor(name, age){ 757 | this.name = name; 758 | this.age = age; 759 | } 760 | 761 | // metodos 762 | speak (){ 763 | return "Hello"; 764 | } 765 | 766 | greeting(){ 767 | return `${this.speak()} ${this.name}`; 768 | } 769 | 770 | get uAge() { //get obtener. Obtener el valor de age 771 | return this.age; 772 | } 773 | 774 | set uAge(n) { //set asignar. Asignar al age el valor de n 775 | this.age = n; 776 | } 777 | } 778 | 779 | const platzi = new user("Ferney Nava", 26); 780 | console.log(platzi.uAge); 781 | console.log(platzi.uAge = 20); 782 | ``` 783 | 784 | #### Module 785 | 786 | ES6 introduce una forma de manejar código en archivos de manera modular. Esto involucra **exportar** funciones o variables de un archivo, e **importarlas** en otros archivos donde se necesite. 787 | 788 | *Cómo utilizar los módulos de ECMAScript* 789 | 790 | Para utilizar los módulos, debes tener mínimo dos archivos, uno para exportar las funciones y otro que las importe para ejecutarlas. 791 | 792 | Es importante de que si iniciaste un proyecto con NPM (Node Package Manager) con Node.js, necesitas especificar que el código es modular en el archivo.json de la siguiente manera: 793 | 794 | ```json 795 | // package.json 796 | { ... 797 | "type": "module" 798 | } 799 | ``` 800 | 801 | *Exportaciones de código* 802 | 803 | Consiste en crear funciones o variables para utilizarlas en otros archivos mediante la palabra reservada **export**. 804 | 805 | Por ejemplos, en el archivo *math_function.js* declaramos una función para sumar dos valores, el cual lo exportaremos. 806 | 807 | ```js 808 | //math_function.js 809 | export const add = (x,y) => { 810 | return x + y 811 | } 812 | ``` 813 | 814 | ```js 815 | //math_function.js 816 | const add = (x,y) => { 817 | return x + y 818 | } 819 | 820 | export { add, otherFunction, ...} 821 | ``` 822 | 823 | *Qué son las importaciones de código* 824 | 825 | Consiste en usar funciones o variables de otros archivos mediante la palabra reservada **import**, deberán estar siempre lo más arriba del archivo y utilizando el mismo nombre que el archivo original. 826 | 827 | Por ejemplos, importamos la función *add* del archivo *math_function.js* para utilizarla en un archivo *main.js* 828 | 829 | ```js 830 | // main.js 831 | 832 | import { add, otherFunction } from "./math_functions.js" 833 | 834 | add(2,2) // 4 835 | ``` 836 | 837 | Si importamos el módulo con un nombre diferente, existirá un error de sintaxis. 838 | 839 | Para importar todas las funcionalidades de un archivo se utiliza un asterisco ( * ) y se puede cambiar el nombre para evitar la repetición de variables o funciones a través de la palabra reservada *as*. 840 | 841 | ```js 842 | // main.js 843 | 844 | import * as myMathModule from "./math_functions.js" 845 | 846 | myMathModule.add(2,2) // 4 847 | myMathModule.otherFunction() 848 | ``` 849 | 850 | *Exportaciones por defecto* 851 | 852 | Si solo un valor será exportado, se puede utilizar **export default**. De esta manera no es necesario las llaves {} al exportar e importar. 853 | 854 | ```js 855 | //math_function.js 856 | 857 | export default function add (x,y){ 858 | return x + y; 859 | } 860 | ``` 861 | 862 | No se puede usar export default antes de declaraciones *const*, *let* o *var*, pero puedes exportarlas al final. 863 | 864 | ```js 865 | // ❌ Erróneo 866 | export default const add = (x,y) => { 867 | return x + y; 868 | } 869 | 870 | // ✅ Correcto 871 | const add = (x,y) => { 872 | return x + y; 873 | } 874 | 875 | export default add 876 | ``` 877 | 878 | *Importaciones por defecto* 879 | 880 | Si únicamente un valor será importado, entonces se puede utilizar cualquier nombre en la importación. De esta manera no se necesario las llaves {}. 881 | 882 | ```js 883 | //Las siguientes importaciones son válidas 884 | import add from './math_functions.js' 885 | import suma from './math_functions.js' 886 | import cualquierNombre from './math_functions.js' 887 | ``` 888 | 889 | *Combinar ambos tipos de exportaciones e importaciones* 890 | 891 | Teniendo las importaciones y exportaciones, nombradas y por defecto, entonces podemos combinarlas en un mismo archivo. 892 | 893 | ```js 894 | // module.js 895 | 896 | export const myExport = "Hola" 897 | function myFunction() { ... } 898 | 899 | export default myFunction 900 | 901 | // main.js 902 | import myFunction, { myExport } from "/module.js" 903 | ``` 904 |

(⬆ Volver a índice)

905 | 906 | --- 907 | 908 | #### Generator 909 | 910 | Son funciones especiales que pueden pausar su ejecución, luego volver al punto donde se quedaron, recordando su scope y seguir retornando valores. 911 | 912 | *Cómo utilizar generadores* 913 | 914 | La sintaxis de los generadores es la siguiente: 915 | 916 | - La palabra reservada function* (con el asterisco al final) 917 | - La palabra reservada *yield* que hace referencia al valor retornado cada vez que se invoque, recordando el valor anterior. 918 | - Crear una variable a partir de la función generadora. 919 | - El método *next* devuelve un objeto que contiene una propiedad *value* con cada valor de yield; y otra propiedad *done* con el valor *true* o *false* si el generador ha terminado. 920 | 921 | ```js 922 | function* nombre (parámetros){ 923 | yield (primer valor retornado) 924 | yield (segundo valor retornado) 925 | ... 926 | yield (último valor retornado) 927 | } 928 | 929 | //crear el generador 930 | const generador = nombre(argumentos) 931 | 932 | // Invocaciones 933 | generador.next().value // primer valor retornado 934 | generador.next().value // segundo valor retornado 935 | ... 936 | generador.next().value // último valor retornado 937 | ``` 938 | 939 | *Ejemplo de un generador* 940 | 941 | ```js 942 | function* generator (){ 943 | yield 1 944 | yield 2 945 | yield 3 946 | } 947 | 948 | const generador = generator() 949 | 950 | generador.next().value // 1 951 | generador.next().value // 2 952 | generador.next().value // 3 953 | generador.next() // {value: undefined, done: true} 954 | ``` 955 | 956 | *Cómo utilizar for of y for in* 957 | 958 | Existen dos nuevas formas de utilizar ciclos repetitivos. El bucle **for valor of iterable** recorre iterables, como arrays, Map, Set e incluso un generador. 959 | 960 | El valor es cada elemento del iterable, se inicia con *let nombre*. Puede tener cualquier nombre. 961 | 962 | ```js 963 | const array = [5, 6, 3, 2, 1] 964 | 965 | for (let numero of array){ 966 | console.log(numero) // 5, 6, 3, 2, 1 967 | } 968 | ``` 969 | 970 | Hay que tener en cuenta que solo podrás acceder a sus valores, y no a sus referencias, por lo que si quieres cambiar los elementos del array, necesitarás un índice array(índice). 971 | 972 | ```js 973 | for (let numero of array){ 974 | numero *= 2 975 | console.log(numero) // 10 12 6 4 2 976 | } 977 | 978 | console.log(array) // [5, 6, 3, 2, 1] 979 | ``` 980 | 981 | Si intentas recorrer un objeto de esta forma *for elemento of objeto*, ocurrirá un error, porque un objeto no es un iterable. En su lugar se utiliza *for elemento in objeto*, que recorrerá las propiedades del objeto. 982 | 983 | ```js 984 | const objeto = { a: 1, b: 2, c: 3 } 985 | 986 | for(let elemento in objeto) { 987 | console.log(elemento) // "a" "b" "c" 988 | } 989 | ``` 990 | 991 | Si utiliza *for elemento in array*, no dará error, pero el resultado no será el esperado, puesto de que los arrays son un tipo de objeto donde cada propiedad es el índice del valor del array o del iterable. 992 | 993 | ```js 994 | const array = { 5, 4, 3, 2, 1 } 995 | 996 | for(let elemento in array) { 997 | console.log(elemento) // "0" "1" "2" "3" "4" 998 | } 999 | ``` 1000 | 1001 |

(⬆ Volver a índice)

1002 | 1003 | --- 1004 | 1005 | #### Set-add 1006 | 1007 | Es una nueva estructura de datos para almacenar elementos únicos, es decir, sin elementos repetidos. 1008 | 1009 | *Cómo utilizar los Sets* 1010 | 1011 | Para iniciar un *Set*, se debe crear una instancia de su clase a partir de un iterable. Un iterable es un objeto que permite recorrer una colección, como por ejemplo un *array* 1012 | 1013 | ```js 1014 | const set = new Set(iterable) 1015 | ``` 1016 | 1017 | *Manipular los Sets* 1018 | 1019 | Para manipular los sets, existen los siguiente métodos: 1020 | 1021 | - add(value): Añade un nuevo valor. 1022 | - delete(value): Elimina un elemento que contiene el Set, retorna un booleano si existía o no el valor. 1023 | - has(value): Retorna un booleano si existe o no el valor dentro del Set. 1024 | - clear(value): Elimina todos los valores del Set. 1025 | - size: Retorna la cantidad de elementos del Set. 1026 | 1027 | **Recurso Map y Set [javaScript.info](https://es.javascript.info/map-set#filtrar-miembros-unicos-del-array)** 1028 | 1029 |

(⬆ Volver a índice)

1030 | 1031 | --- 1032 | 1033 | ### ECMAScript 7 (ES7 o ES2016) 1034 | 1035 | #### Operador de potenciación y array includes 1036 | 1037 | Consiste en elevar una base a un exponente utilizando el doble asterisco ( ** ) 1038 | 1039 | **base ** exponente** 1040 | 1041 | Ejemplo, calcula la potencia del siguiente número 5^3 1042 | 1043 | ```js 1044 | const potencia = 5**3 1045 | 1046 | console.log(potencia) // 125 1047 | ``` 1048 | 1049 | *Método includes* 1050 | 1051 | Determina si un array o string incluye un determinado elemento. Devuelve **true** o **false**, si existe o no respectivamente. 1052 | 1053 | Este método recibe dos argumentos: 1054 | - El elemento a comparar 1055 | - El índice inicial desde donde comparar hasta el último elemento. 1056 | 1057 | *Índices positivos y negativos* 1058 | 1059 | Los índices positivos comienzan desde 0 hasta la longitud total menos uno, de izquierda a derecha del array. 1060 | 1061 | ```js 1062 | [0,1,2,3,....., lenght-1] 1063 | ``` 1064 | 1065 | Los índices negativos comienzan desde -1 hasta el negativo de la longitud total del *array*, de derecha a izquierda. 1066 | 1067 | ```js 1068 | [-lenght, ..., -3, -2, -1] 1069 | ``` 1070 | 1071 | *Ejemplos utilizando el método includes* 1072 | 1073 | Método includes se utiliza para arrays y strings. El método es sensible a mayúsculas, minúsculas y espacios. 1074 | 1075 | ```js 1076 | // Utilizando strings 1077 | const saludo = "Hola mundo" 1078 | 1079 | saludo.includes("Hola") // true 1080 | saludo.includes("Mundo") // false 1081 | saludo.includes(" ") // true 1082 | saludo.includes("Hola", 1) // false 1083 | saludo.includes("mundo", -5) // true 1084 | ``` 1085 | 1086 | ```js 1087 | // Utilizando arrays 1088 | const frutas = ["manzana", "pera", "piña", "uva"] 1089 | 1090 | frutas.includes("manzana") // true 1091 | frutas.includes("Pera") // false 1092 | frutas.includes("sandía") // false 1093 | frutas.includes("manzana", 1) // false 1094 | frutas.includes("piña", -1) // false 1095 | frutas[0].includes("man") // true 1096 | ``` 1097 | 1098 | En objetos también existen formas para saber si existe una propiedad. Solo evalúa las clases de los objetos. Con la siguiente palabra reservada y los siguientes métodos. 1099 | 1100 | - La palabra reservada in; evalúa todas las propiedades del objeto y del prototipo. 1101 | - El método de objetos **hasOwnProperty**; Evalúa solamente las propiedades del objeto. 1102 | - El método **Object.hasOwm**, que recibe el objeto y la propiedad a evaluar. 1103 | 1104 | ```js 1105 | // Utilizando arrays 1106 | const letras = { 1107 | a: 1, 1108 | b: 2, 1109 | c: 3 1110 | } 1111 | 1112 | console.log("a" in letras) //true en el objeto se encuentra la clave "a" 1113 | console.log(letras.hasOwmProperty("a")) // true en el objeto se encuentra la clave "a" 1114 | console.log(Object.hasOwm(letras, "a")) // true en el objeto se encuentra la clase "a" 1115 | 1116 | const letrass = {d: 4, e: 5, f: 7} 1117 | 1118 | console.log(letrass) 1119 | console.log(letrass.hasOwmProperty("toString")) // false 1120 | console.log("toString" in letras) // true por el objeto letrass tiene una prototipo que se llama toString 1121 | ``` 1122 | 1123 |

(⬆ Volver a índice)

1124 | 1125 | --- 1126 | 1127 | ### ECMAScript 8 (ES8 o ES2017) 1128 | 1129 | #### Object entries y object values 1130 | 1131 | Los métodos de transformación de objectos a *arrays* sirven para obtener la información de las propiedades, sus valores o ambas. Devuelve una matriz de pares clave-valor. 1132 | 1133 | *Obtener los pares de valor de un objeto en un array* 1134 | 1135 | *Object.entries()* devuelve un *array* con las entries en forma [propiedad, valor] del objeto enviado como argumento. 1136 | 1137 | ```js 1138 | const usuario = { 1139 | name: "Ferney", 1140 | email: "ferneynava@gmail.com" 1141 | age: 26 1142 | } 1143 | 1144 | Object.entries(usuario) 1145 | /* 1146 | [ 1147 | [ "name", "ferney"], 1148 | [ "email", "ferneynava@gmail.com"], 1149 | [ "age", 23] 1150 | ] 1151 | */ 1152 | ``` 1153 | 1154 | *Obtener las propiedades de un objeto en un array* 1155 | 1156 | *Object.keys()* devuelve un array con las propiedades (*keys*) del objeto enviado como argumento. 1157 | 1158 | ```js 1159 | const usuario = { 1160 | name: "Ferney", 1161 | email: "ferneynava@gmail.com" 1162 | age: 26 1163 | } 1164 | 1165 | Object.keys(usuario) 1166 | // ["name", "email", "age"] 1167 | ``` 1168 | 1169 | *Obtener los valores de un objeto en un array* 1170 | 1171 | *Object.values()* devuelve un *array* con los valores de cada propiedad del objeto enviado como argumento. 1172 | 1173 | ```js 1174 | const usuario = { 1175 | name: "Ferney", 1176 | email: "ferneynava@gmail.com" 1177 | age: 26 1178 | } 1179 | 1180 | Object.values(usuario) 1181 | // ["Ferney", "ferneynava@gmail.com", 26] 1182 | ``` 1183 | 1184 | #### String padding y trailing commas 1185 | 1186 | *Rellenar un string o padding* 1187 | 1188 | Padding consiste en rellenar un *string* por el principio o por el final, con el carácter especificado, repetido hasta que complete la longitud máxima. 1189 | 1190 | Este método recibe dos argumentos: 1191 | 1192 | - La longitud máxima a rellenar, incluyendo el string inicial. 1193 | - El *string* para rellenar, por defecto, es un espacio. 1194 | 1195 | *Método padStart* 1196 | 1197 | Este método completa un *string* con otro *string* en el inicio hasta tener total de caracteres especificado. 1198 | 1199 | ```js 1200 | "abc".padStart(10) // " abc" 1201 | "abc".padStart(10, "foo") //"foofoofabc" 1202 | "abc".padStart(6, "123456") //123abc" 1203 | "abc".padStart(8, "0") //00000abc 1204 | "abc".padStart(1) // "abc" 1205 | ``` 1206 | 1207 | *Método padEnd* 1208 | 1209 | Este método completa un *string* con otro *string* en el final hasta tener un total de caracteres especificado. 1210 | 1211 | ```js 1212 | "abc".padEnd(10) // "abc " 1213 | "abc".padEnd(10, "foo") // "abcfoofoof" 1214 | "abc".padEnd(6, "123456") // "abc123" 1215 | "abc".padEnd(1) // "abc" 1216 | ``` 1217 | 1218 | *Trailing commas* 1219 | 1220 | Consisten en comas al final de objetos o arrays que facilitan añadir nuevos elementos y evitar errores de sintaxis. 1221 | 1222 | ```js 1223 | const usuario = { 1224 | name: "Ferney", 1225 | email: "ferneynava@gmail.com" 1226 | age: 26, //<-- Trailing comma 1227 | } 1228 | 1229 | const nombres = [ 1230 | "Ferney", 1231 | "Erika", 1232 | "Pedro", //<--- Trailinf comma 1233 | ] 1234 | ``` 1235 | 1236 |

(⬆ Volver a índice)

1237 | 1238 | --- 1239 | 1240 | #### Funciones asíncronas 1241 | 1242 | *funciones asíncronas* 1243 | 1244 | La función asíncrona se crea mediante la palabra reservada *async* y retorna una promesa. 1245 | 1246 | ```js 1247 | async funcition asyncFunction () {...} 1248 | 1249 | const asyncFunction = async () => {...} 1250 | ``` 1251 | 1252 | La palabra reservada await **significa que espera hasta que una promesa sea resuelta** y solo funciona dentro de una función asíncrona. Los bloques try / catch sirven para manejar si la promesa ha sido resuelta o rechazada. 1253 | 1254 | ```js 1255 | async funcition asyncFunction () { 1256 | try { 1257 | const respuesta = await promesa() 1258 | return respuesta 1259 | } catch (error) { 1260 | return error 1261 | } 1262 | } 1263 | ``` 1264 | 1265 |

(⬆ Volver a índice)

1266 | 1267 | --- 1268 | 1269 | ### ECMAScript 9 (ES9 o ES2018) 1270 | 1271 | #### Expresiones regulares 1272 | 1273 | Las expresiones regulares o RegEx (regular expresions) son **patrones de búsqueda y manipulación de cadenas de caracteres**. 1274 | 1275 | En JavaScript se crea este patrón entre barras inclinadas (/patrón/) y se utiliza métodos para hacer coincidir la búsqueda. 1276 | 1277 | ```js 1278 | const regexData = /([0-9]{4})-([0-9]{2})-([0-9]{2})/ 1279 | const match = regesData.exec("2018-04-20") 1280 | ``` 1281 | 1282 |

(⬆ Volver a índice)

1283 | 1284 | --- 1285 | 1286 | #### Promise.finally 1287 | 1288 | *Método finally en promesas* 1289 | 1290 | Consiste en ejecutar código después que una promesa haya sido ejecutada como resultado o rechazada. 1291 | 1292 | ```js 1293 | promesa() 1294 | .then(response => console.log(response)) // Promesa resuelta 1295 | .catch(error => console.log(error)) // Promesa rechazada 1296 | .finally(() => console.log("Finalizado")) // Código final 1297 | ``` 1298 | 1299 | *Generados asíncronos* 1300 | 1301 | Los generadores asíncronos son semejantes a los [Generadores](#generator), pero combinando sintaxis de promesas. 1302 | 1303 | ```js 1304 | async function* anotherGenerator(){ 1305 | yield await Promise.resolve(1) 1306 | yield await Promise.resolve(2) 1307 | yield await Promise.resolve(3) 1308 | } 1309 | 1310 | const generador = anotherGenerator() 1311 | generador.next().then(respuesta => console.log(respuesta.value)) 1312 | generador.next().then(respuesta => console.log(respuesta.value)) 1313 | generador.next().then(respuesta => console.log(respuesta.value)) 1314 | ``` 1315 | 1316 | *Cómo utilizar for await* 1317 | 1318 | *for await* 1319 | 1320 | Es un ciclo repetitivo que se maneja asíncronamente. El ciclo siempre debe estar dentro de una función con *async*. 1321 | 1322 | El valor es cada elemento del iterable puede tener cualquier nombre. 1323 | 1324 | ```js 1325 | async function forAwait(){ 1326 | const nombre = ["Ferney", "Erika", "Pedro"] 1327 | for await(let valor of nombre) { 1328 | console.log(valor) 1329 | } 1330 | } 1331 | ``` 1332 |

(⬆ Volver a índice)

1333 | 1334 | --- 1335 | 1336 | ### ECMAScript 10 (ES10 o ES2019) 1337 | 1338 | #### Flat-map y trimStart-trimEnd 1339 | 1340 | *Qué es el aplanamiento de arrays* 1341 | 1342 | Consiste en transformar un array de arrays a una sola dimensión. Los métodos *flat* y *flatMap* permitirán realizar el aplanamiento. 1343 | 1344 | *Método flat* 1345 | 1346 | Devuelve un *array* donde los sub-arrays han sido propagados hasta una profundidad especifica. 1347 | 1348 | Este método es inmutable, es decir, retorna un nuevo array con los cambios y no cambia el array original. 1349 | 1350 | Este método recibe un argumento: 1351 | 1352 | - La *profundidad* del aplanamiento, por defecto, tiene un valor de 1. 1353 | 1354 | Se puede aplanar todos los sub-arrays en una sola dimensión, utilizando el valor de *Infinity* 1355 | 1356 | ```js 1357 | const array = [1,2[3,4],5,6] 1358 | const result = array.flat() 1359 | result // [1,2,3,4,5,6] 1360 | 1361 | const array2 = [1, 2, [3, 4, [5, 6]]] 1362 | const result2 = array2.flat() 1363 | result2 // [1, 2, 3, 4, [5, 6]] 1364 | 1365 | const array3 = [1, 2, [3, 4, [5, 6]]] 1366 | const result3 = array3.flat(2) 1367 | result3 // [1, 2, 3, 4, 5, 6] 1368 | 1369 | const array4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]] 1370 | const result4 = array4.flat(Infinity) 1371 | result4 // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 1372 | ``` 1373 | 1374 | *Método flatMap* 1375 | 1376 | Es un combinación de los métodos *map* y *flat*. Primero realiza la interacción de los elementos del array (como si fuera map), y después los aplana en una sola profundidad (como si fuera *flat*) 1377 | 1378 | Este método es **inmutable**, es decir, retorna un nuevo array con los cambios y no cambia el array original. 1379 | 1380 | El método recibe los mismos argumentos que el método map. 1381 | 1382 | ```js 1383 | const strings = ["Nunca pares", "de Aprender"] 1384 | strings.map(string => string.split("")) 1385 | // [['Nunca', 'pares'], ['de', 'Aprender']] 1386 | strings.flatMap(string => string.split("")) 1387 | // ['Nunca', 'pares', 'de', 'Aprender'] 1388 | 1389 | const numbers = [1,2,3,4] 1390 | numbers.map(number => [number * 2]) 1391 | // [[2],[4],[6],[8]] 1392 | numbers.flatMap(number => [number *2]) 1393 | // [2,4,6,8] 1394 | 1395 | // Cuidado, primero hace el map y luego el flat 1396 | const numbers2 = [1,[2,3], 4, 5] 1397 | numbers2.flatMap(number => [number * 2]) 1398 | // [2, NaN, 8, 10] 1399 | // Recuerda: NaN = No a Number 1400 | ``` 1401 | 1402 | *Eliminar espacios en blanco de un string* 1403 | 1404 | Existen tres métodos para *eliminar espacio en blanco* de un string 1405 | 1406 | - El método *trim* elimina los espacios en blanco al inicio y al final. 1407 | - EL método *trimStart* o *trimLeft* elimina los espacios al inicio. 1408 | - El método *trimEnd* o *trimRight* elimina los espacios al final. 1409 | 1410 | ```js 1411 | const saludo = " hola " 1412 | const result1 = saludo.trim() 1413 | const result2 = saludo.trimStart() 1414 | const result3 = saludo.trimEnd() 1415 | 1416 | result1 // "hola" 1417 | result2 // "hola " 1418 | result3 // " hola" 1419 | ``` 1420 | 1421 |

(⬆ Volver a índice)

1422 | 1423 | --- 1424 | 1425 | #### Try catch y fromEntries 1426 | 1427 | *Parámetro opcional de catch* 1428 | 1429 | El parámetro de *catch*, permite omitir el error si es necesario. 1430 | 1431 | ```js 1432 | try { 1433 | // Manejar el código 1434 | } catch (err) { 1435 | // Se utiliza el parámetro 'err' 1436 | } 1437 | 1438 | try { 1439 | // Manejar el código 1440 | } catch { 1441 | // Manejar el error sin el parámetro. 1442 | } 1443 | ``` 1444 | 1445 | Se recomienda manejar el error como parámetro, puesto de que tiene más información del problema. 1446 | 1447 | *Cómo transformar un array de arrays en un objeto* 1448 | 1449 | El método **Object.fromEntries** devuelve un objeto a partir de un arrays donde sus elementos son las *entries* en forma [propiedad, valor] 1450 | 1451 | Se puede considerar la opción inversa de **Object.entries()**. *entries()* transforma el objectos a arrays y en cambio el *fromEntries()* transforma el array en objeto. 1452 | 1453 | ```js 1454 | const arrayEntries = [ 1455 | ['name', 'Ferney'], 1456 | ['email', 'ferneynava@gmail.com'], 1457 | ['age', 26] 1458 | ] 1459 | 1460 | const usuario = Object.fromEntries(arrayEntries) 1461 | 1462 | console.log(usuario) 1463 | /* { 1464 | name: 'Ferney', 1465 | email: 'ferneynava@gmail.com' 1466 | age: 26 1467 | } 1468 | ``` 1469 | 1470 |

(⬆ Volver a índice)

1471 | 1472 | --- 1473 | 1474 | ### ECMAScript 11 (ES11 o ES2020) 1475 | 1476 | #### Optional chaining 1477 | 1478 | Cuando intentas acceder a propiedades de un objeto que no existen, JavaScript retornará *undefined*. 1479 | 1480 | ```js 1481 | const usuario = {} 1482 | console.log(usuario.redes) // undefined 1483 | ``` 1484 | 1485 | Al acceder a una propiedad más profunda de un objeto, que previamente fue evaluada como *undefined*, el programa se detendrá y mostrará un error. 1486 | 1487 | ```js 1488 | const usuario = {} 1489 | console.log(usuario.redes.facebook) 1490 | // TypeError: Cannot read properties of undefined (reading 'facebook') 1491 | ``` 1492 | 1493 | Ejecutar *undefined.facebook* es un error de tipo, debido a que *undefined* es un primitivo, no es un objeto. 1494 | 1495 | *Cómo utilizar el encadenamiento opcional* 1496 | 1497 | Optional chaining (?.) detiene la evaluación del objeto cuando el valor es *undefined* o *null* antes del (?.), retornara *undefined* sin detener el programa por un error. 1498 | 1499 | ```js 1500 | const usuario = {} 1501 | console.log(usuario.redes?.facebook) 1502 | //undefined 1503 | ``` 1504 | 1505 | Pero, ¿por qué usaría propiedades de un objeto vacío? Cuando realizas peticiones, el objeto no contiene la información solicitada en seguida, por ende, necesitas que el programa no colapse hasta que lleguen los datos y puedas utilizarlos. 1506 | 1507 | *No abuses del encadenamiento opcional* 1508 | 1509 | El encadenamiento opcional se debe utilizar únicamente cuando probablemente un valor no exista. 1510 | 1511 | Por ejemplo, en un objeto *usuario* que siempre existe, pero la propiedad redes es opcional, entonces se debería escribir *usuario.redes?.facebook* y no *usuario?.redes?.facebook*. 1512 | 1513 | Si abusas del encademiento opcional y existe un error en un objeto, el programa podría "ocultarlo" por un *undefined*, provocando que el *debugging* sea más complicado. 1514 | 1515 |

(⬆ Volver a índice)

1516 | 1517 | --- 1518 | 1519 | #### BigInt y Nullish 1520 | 1521 | *BigInt, números enteros muy grandes* 1522 | 1523 | El dato primitivo *bigint* permite **manejar números enteros muy grandes**. Existen dos formas de crear un *bigint*: el número entero seguido de *n* o mediante la función *BigInt*. 1524 | 1525 | ```js 1526 | const aBigNumber = 899867566537653456456n 1527 | const anotherBigNumber = BigInt(899867566537653456456) 1528 | 1529 | typeof 899867566537653456456n // "bigint" 1530 | ``` 1531 | 1532 | JavaScript tiene límites numéricos, un máximo **Number.MAX_SAFE_INTEGER** y un mínimo **Number.MIN_SAFE_INTEGER** 1533 | 1534 | ```js 1535 | const max = Number.MAX_SAFE_INTEGER // 9007199254740991 1536 | const min = Number.MIN_SAFE_INTEGER // -9007199254740991 1537 | ``` 1538 | 1539 | Al pasar de los limites anteriormente mencionados, los cálculos muestran resultados erróneos. Los *bigint* ayudan a manejar operaciones de enteros fuera de los límites. 1540 | 1541 | ```js 1542 | const increment = 2 1543 | const number = Number.MAX_SAFE_INTEGER + increment // 9007199254740992 sin el BigInt 1544 | const bigInt = BigInt(Number.MAX_SAFE_INTEGER) + BigInt(increment) //9007199254740993n con el BigInt 1545 | ``` 1546 | 1547 | Se añade la misma cantidad a ambos tipos de datos, sin embargo, el tipo numérico da un resultado diferente al esperado. 1548 | 1549 | *Operador Nullish Coalescing* 1550 | 1551 | El operador nullish coalescing ( ?? ) consiste en evaluar una variable si es *undefined* o *null* para asignarle un valor. 1552 | 1553 | El siguiente ejemplo se lee como: ¿usuario.name es undefined o null? Si es así, asígnale un valor por defecto "Ferney", caso contrario asigna el valor de usuario.name. 1554 | 1555 | ```js 1556 | const usuario1 = {} 1557 | const nombre1 = usuario1.name ?? "Ferney" 1558 | 1559 | const usuario2 = {name: "Camilo"} 1560 | const nombre2 = usuario2.name ?? "Ferney" 1561 | 1562 | console.log(nombre1) // 'Ferney' 1563 | console.log(nombre2) // 'Camilo' 1564 | ``` 1565 | 1566 | *Diferencia entre el operador OR y el Nullish coalescing* 1567 | 1568 | El operador OR ( || ) evalúa un valor false. Un valor false es aquel que es falso en un contexto booleano, estos son: 0, "" (string vacío), false, NaN, undefined o null. 1569 | 1570 | Puede que reciba una variable con un valor false que necesitas asignarle a otra variable, que no sea null o undefined. Si evalúas con el operador OR, este lo cambiará, provocando un resultado erróneo. 1571 | 1572 | ```js 1573 | const id = 0 1574 | 1575 | const orId = id || "Sin id" 1576 | const nullish = id ?? "Sin id" 1577 | 1578 | console.log(orId) // Sin id 1579 | console.log(nullish) // 0 1580 | ``` 1581 | 1582 |

(⬆ Volver a índice)

1583 | 1584 | --- 1585 | 1586 | #### Promise.allSettled 1587 | 1588 | *Promise.all* 1589 | 1590 | El método *Promise.all* sirve para manejar varias promesas al mismo tiempo. Recibe como argumento un *array* de promesas. 1591 | 1592 | ```js 1593 | Promise.all([promesa1, promesa2, promesa3]) 1594 | .then(respuesta => console.log(respuesta)) 1595 | .catch(error => console.log(error)) 1596 | ``` 1597 | 1598 | El problema es que *Promise.all()* se resolverá, si y solo si **todas las promesas fueron resueltas**. Si al menos una promesa es rechazada, *Promise.all()* será rechazada. 1599 | 1600 | *Promise.allSettled* 1601 | 1602 | Permite manejar varias promesas, que devolverá un *array* de objetos con el estado y el valor de cada promesa, haya sido resuelta o rechazada. 1603 | 1604 | ```js 1605 | const promesa1 = Promise.reject("Ups promesa 1 falló") 1606 | const promesa2 = Promise.resolve("Promesa 2") 1607 | const promesa3 = Promise.reject("Ups promesa 3 falló") 1608 | 1609 | Promise.allSettled([promesa1, promesa2, promesa3]) 1610 | .then(respuesta => console.log(respuesta)) 1611 | 1612 | /* [ 1613 | { 1614 | status: "rejected", 1615 | reason: "Ups promesa 1 fallo" 1616 | }, 1617 | { 1618 | status: "fulfilled", value: "Promesa 2" 1619 | }, 1620 | { 1621 | status: "reject", 1622 | reason: "Ups promesa 3 fallo" 1623 | } 1624 | ] */ 1625 | ``` 1626 | 1627 |

(⬆ Volver a índice)

1628 | 1629 | --- 1630 | 1631 | #### GlobalThis y matchAll 1632 | 1633 | *Objeto global para cualquier plataforma* 1634 | 1635 | El motor de JavaScript, compila tu archivo y lo convierte en código que entiende el computador, al iniciar la compilación crea un objeto global. 1636 | 1637 | Este objeto global proporciona funciones y variables propias e integradas en el lenguaje o el entorno. Dependiendo la plataforma, este objeto global tendrá un nombre diferente. 1638 | 1639 | En el navegador el objeto global es *window*, para Node.js es *global*, y así para cada entorno. Sin embargo, en Node.js no podrás acceder a *window*, ni en el navegador podrás acceder a *global*. 1640 | 1641 | Para estandarizar el objeto global se creó *globalThis*, un objeto compatible para cualquier plataforma. 1642 | 1643 | ```js 1644 | // Ejecuta el siguiente código y observa que muestra 1645 | console.log(window) 1646 | console.log(globalThis) 1647 | 1648 | // En el navegador 1649 | window === globalThis // true 1650 | 1651 | // En Node.js 1652 | 1653 | global === globalThis // true 1654 | ``` 1655 | 1656 | *Método matchAll para expresiones regulares* 1657 | 1658 | El método matchAll de los strings **devuelve un iterable** con todas las coincidencias del strings específico a partir de una expresión regular, colocada como argumento. 1659 | 1660 | ```js 1661 | const regex = /\b(Apple)+\b/g 1662 | const fruit = "Apple, Banana, Kiwi, Apple, Orange, etc. etc. etc." 1663 | 1664 | // Transformación del iterable retornado a array 1665 | const array = [...fruit.matchAll(regex)] 1666 | console.log(array) 1667 | 1668 | /* 1669 | [ 1670 | [ 1671 | 'Apple', 1672 | 'Apple', 1673 | index: 0, 1674 | input: 'Apple, Banana, Kiwi, Apple, Orange, etc. etc. etc.', 1675 | groups: undefined 1676 | ], 1677 | [ 1678 | 'Apple', 1679 | 'Apple', 1680 | index: 21, 1681 | input: 'Apple, Banana, Kiwi, Apple, Orange, etc. etc. etc.', 1682 | groups: undefined 1683 | ] 1684 | ] 1685 | */ 1686 | ``` 1687 | 1688 |

(⬆ Volver a índice)

1689 | 1690 | --- 1691 | 1692 | #### Dynamic Import 1693 | 1694 | *Cómo utilizar importación dinámica* 1695 | 1696 | Consiste en cargar los módulos cuando el usuario los vaya a utilizar, y no al iniciar la aplicación. Permite que la página web sea más rápida, porque descarga menos recursos. 1697 | 1698 | La expresión *import()* recibe un argumento de tipo string con la ruta del módulo a importar y devuelve una promesa. 1699 | 1700 | ```js 1701 | const ruta = "./modulo.js" 1702 | 1703 | // Utilizando promesas 1704 | import(ruta) 1705 | .then( modulo => { 1706 | modulo.funcion1() 1707 | modulo.funcion2() 1708 | }) 1709 | .catch(error => console.log(error)) 1710 | 1711 | // Uilizando async/await 1712 | async function importarModulo(rutaDelModulo){ 1713 | const modulo = await import(rutaDelModulo) 1714 | modulo.function1() 1715 | modulo.function2() 1716 | } 1717 | 1718 | importarModulo(ruta) 1719 | ``` 1720 | 1721 | *Ejemplo utilizando importación dinamica* 1722 | 1723 | De esta manera puedes utilizar una importación dinámica en tu aplicación para desencadenar una descarga de un módulo cuando el usuario lo vaya a utilizar. Por ejemplo, al realizar clic en un botón. 1724 | 1725 | ```js 1726 | const boton = document.getElementById("boton") 1727 | 1728 | boton.addEventListener("click", async function() { 1729 | const modulo = await import("./modulo.js") 1730 | modulo.funcion() 1731 | }) 1732 | ``` 1733 | 1734 |

(⬆ Volver a índice)

1735 | 1736 | --- 1737 | 1738 | ### ECMAScript 12 (ES12 o ES2021) 1739 | 1740 | #### Numeric-separators y replaceAll 1741 | 1742 | *Separadores numéricos* 1743 | 1744 | Ayudan a la legibilidad de cantidades con varias cifras. Se utiliza el carácter guion bajo ( _ ) para separar las cifras, y no afecta a la ejecución del programa. 1745 | 1746 | Lo ideal es separar cada 3 cifras, para visualizar los miles, millones, billones, etc. 1747 | 1748 | ```js 1749 | // Baja legibilidad 1750 | const numero1 = 3501548945 1751 | console.log(numero1) // 3501548945 1752 | 1753 | // Alta legibilidad 1754 | const numero2 = 3_501_548_945 1755 | console.log(numero2) // 3501548945 1756 | ``` 1757 | 1758 | De esta manera podemos identificar el número rápidamente. 1759 | 1760 | *Método replaceAll* 1761 | 1762 | El método *replaceAll* retorna un nuevo string, remplazando todos los elementos por otro. 1763 | 1764 | Este método recibe dos argumentos: 1765 | - El patrón a reemplazar, puede ser un string o una expresión regular. 1766 | - El nuevo elemento que sustituye al reemplazado. 1767 | 1768 | Este método soluciona el problema que tenía *replace*, que realizaba la misma función de reemplazar elementos, pero solamente *una sola vez* por invocación. 1769 | 1770 | ```js 1771 | const mensaje = "JavaScript es maravilloso, con JavaScript puede crear el futuro de la web." 1772 | 1773 | mensaje.replace("JavaScript", "Python") 1774 | // "Python es maravillo, con JavaScript puede crear el futuro de la web." 1775 | 1776 | mensaje.replaceAll("JavaScript", "Python") 1777 | // "Puthon es maravillo, con Python puede crear el futuro de la web." 1778 | 1779 | mensaje.replaceAll(/a/g, "*") 1780 | // "J*v*Script es m*r*villoso, con J*v*Script puede cre*r el futuro de l* web." 1781 | ``` 1782 | 1783 |

(⬆ Volver a índice)

1784 | 1785 | --- 1786 | 1787 | #### Promise-any y métodos privados 1788 | 1789 | *Métodos privados de clases* 1790 | 1791 | Consiste en *limitar el acceso a propiedades y métodos* agregando el carácter numeral ( # ). Por defecto, las propiedades y métodos de una clase en JavaScript son públicas, es decir, se puede acceder a ellos fuera de la clase. 1792 | 1793 | ```js 1794 | class Clase { 1795 | #private(valor){ 1796 | console.log(valor) 1797 | } 1798 | 1799 | public(valor){ 1800 | console.log(valor) 1801 | } 1802 | } 1803 | 1804 | const clase = new Clase() 1805 | clase.public("Hola") // "Hola" 1806 | clase.private("Hola") // TypeError: clase.private is not a function 1807 | ``` 1808 | 1809 | *Promise.any* 1810 | 1811 | Es otra forma de manejar promesas, que **retornará la primera promesa que sea resuelta** y rebotará si todas las promesas son rechazadas. 1812 | 1813 | ```js 1814 | const promesa1 = Promise.reject("Ups promesa 1 falló") 1815 | const promesa2 = Promise.reject("Ups promesa 2 falló") 1816 | const promesa3 = Promise.resolve("Promesa 3") 1817 | 1818 | Promise.any([promesa1, promesa2, promesa3]) 1819 | .then(respuesta => console.log(respuesta)) 1820 | .catch(error => console.log(error)) 1821 | ``` 1822 | 1823 |

(⬆ Volver a índice)

1824 | 1825 | --- 1826 | 1827 | ### ECMAScript 13 (ES13 o ES2022) 1828 | 1829 | #### At 1830 | 1831 | El método *at* de arrays sirve para **acceder a los elementos a partir del índice.** 1832 | 1833 | *Índices positivos y negativos* 1834 | 1835 | Los índices positivos comienzan desde 0 hasta la longitud total menos uno, de izquierda a derecha del array. 1836 | 1837 | ```js 1838 | [0,1,2,3,....., lenght-1] 1839 | ``` 1840 | 1841 | Los índices negativos comienzan desde -1 hasta el negativo de la longitud total del *array*, de derecha a izquierda. 1842 | 1843 | ```js 1844 | [-lenght, ..., -3, -2, -1] 1845 | ``` 1846 | 1847 | *Cómo utilizar el método at* 1848 | 1849 | La utilidad más importante de este método es para manejar *índices negativos*. Algo que no se puede con la notación de corchetes. 1850 | 1851 | ```js 1852 | const nombres = ["Andres", "Monica", "Damaris", "Lina", "Ramiro"] 1853 | 1854 | nombres.at(-1) // "Ramiro" 1855 | nombres[-1] // undefined 1856 | nombres.at(-3) // Damaris 1857 | nombres[nombres.length - 1] // "Lina" 1858 | ``` 1859 | 1860 | Se puede utilizar la notación de corchetes, pero necesitas obtener la longitud del *array* y restarle una unidad, generando mucho código que puede volverse difícil de leer. 1861 | 1862 | ```js 1863 | const nombres = ["Andres", "Monica", "Damaris", "Lina", "Ramiro"] 1864 | 1865 | nombres[nombres.length - 1] // "Lina" 1866 | ``` 1867 | 1868 |

(⬆ Volver a índice)

1869 | 1870 | --- 1871 | 1872 | #### Top level await en el consumo de una API 1873 | 1874 | Permite utilizar la palabra reservada *await*, sin estar dentro de una función asíncrona con *async*. Sin embargo, únicamente se puede utilizar *await* en la parte superior del archivo de un módulo. 1875 | 1876 | *Cómo utilizar top level await* 1877 | 1878 | Cuando se introdujo funciones asíncronas, si utilizabas *await* fuera de *async*, existirá un error de sintaxis. 1879 | 1880 | ```js 1881 | // Error 1882 | await fetch(URL) 1883 | // SyntaxError: await is only valid in async function 1884 | ``` 1885 | 1886 | Ahora, con *top level await* esto es posible, sin ningún error. Esto puede servir para importaciones de manera dinámica o iniciar la conexión de tus bases de datos. Siempre y cuando respetes que debe estar en la parte encima del archivo de tipo módulo. 1887 | 1888 |

(⬆ Volver a índice)

1889 | 1890 | --- 1891 | 1892 | ### Contribuyendo 1893 | 1894 | Las contribuciones son lo que hace que la comunidad de código abierto sea un lugar increíble para aprender, inspirar y crear. Cualquier contribución que hagas es muy apreciada. 1895 | 1896 | Si tiene una sugerencia que mejoraría esto, bifurque el repositorio y crea una solicitud de extracción. También puede simplemente abrir un problema con la etiqueta "mejora". ¡No olvides darle una estrella al proyecto! ¡Gracias de nuevo! 1897 | 1898 | 1. Bifurcar el repositorio 1899 | 2. Crea tu rama de funciones (`git checkout -b `) 1900 | 3. Confirme sus cambios (`git commit -m "mensaje del commit'`) 1901 | 4. Empuje a la rama (`git push origin branch`) 1902 | 5. Abrir una solicitud de extracción 1903 | 1904 |

(⬆ Volver a índice)

1905 | 1906 | --- 1907 | 1908 | ### Contacto 1909 | 1910 | Ferney Alexander Nava Trujillo - ferneynava@gmail.com 1911 | 1912 |

(⬆ Volver a índice)

1913 | 1914 | --- 1915 | 1916 | ### Expresiones de gratitud 1917 | 1918 | * Ándres Guana Contributor de Platzi 1919 | 1920 |

(⬆ Volver a índice)

1921 | 1922 | 1923 | [contributors-shield]: https://img.shields.io/github/contributors/ferneynava/Curso-de-ECMAScript.svg?style=for-the-badge 1924 | [contributors-url]: https://github.com/ferneynava/Curso-de-ECMAScript/graphs/contributors 1925 | [forks-shield]: https://img.shields.io/github/forks/ferneynava/Curso-de-ECMAScript.svg?style=for-the-badge 1926 | [forks-url]: https://github.com/ferneynava/Curso-de-ECMAScript/network/members 1927 | [stars-shield]: https://img.shields.io/github/stars/ferneynava/Curso-de-ECMAScript.svg?style=for-the-badge 1928 | [stars-url]: https://github.com/ferneynava/Curso-de-ECMAScript/stargazers 1929 | [issues-shield]: https://img.shields.io/github/issues/ferneynava/Curso-de-ECMAScript.svg?style=for-the-badge 1930 | [issues-url]: https://github.com/ferneynava/Curso-de-ECMAScript/issues 1931 | [license-shield]: https://img.shields.io/github/license/ferneynava/Curso-de-ECMAScript.svg?style=for-the-badge 1932 | [license-url]: https://github.com/ferneynava/Curso-de-ECMAScript/blob/master/LICENSE.txt 1933 | [linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=for-the-badge&logo=linkedin&colorB=555 1934 | [linkedin-url]: https://www.linkedin.com/in/ferney-alexander-nava-trujillo-0478a8118/ 1935 | [product-screenshot]: images/screenshot.png 1936 | --------------------------------------------------------------------------------