paint-brush
12 conceptos de JavaScript que mejorarán tus habilidades de desarrollopor@nas5w
110,687 lecturas
110,687 lecturas

12 conceptos de JavaScript que mejorarán tus habilidades de desarrollo

por Nick Scialli2019/02/10
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

JavaScript es un lenguaje complejo. Si es un desarrollador de JavaScript en cualquier nivel, es importante comprender sus conceptos fundamentales. Este artículo aborda 12 conceptos que son fundamentales para que cualquier desarrollador de JS los entienda, pero de ninguna manera representa la amplitud completa de lo que un desarrollador de JS debe saber.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - 12 conceptos de JavaScript que mejorarán tus habilidades de desarrollo
Nick Scialli HackerNoon profile picture

JavaScript es un lenguaje complejo. Si es un desarrollador de JavaScript en cualquier nivel, es importante comprender sus conceptos fundamentales. Este artículo aborda 12 conceptos que son fundamentales para que cualquier desarrollador de JS los entienda, pero de ninguna manera representa la amplitud completa de lo que un desarrollador de JS debe saber.

Nota: si te gusta este artículo, dale un aplauso 👏 (¡o 50!) para ayudar a correr la voz.

Actualizaré continuamente esta lista en un repositorio de Github llamado JS Tips & Tidbits . ¡Estrella ⭐ y comparte si quieres seguirnos!

1. Asignación de valor frente a variable de referencia

Comprender cómo se asigna JavaScript a las variables es fundamental para escribir JavaScript sin errores. Si no entiende esto, podría escribir fácilmente un código que cambie los valores sin querer.

JavaScript siempre asigna variables por valor. Pero esta parte es muy importante: cuando el valor asignado es uno de los cinco tipos primitivos de JavaScript (es decir, Boolean , null , undefined , String y Number ), se asigna el valor real. Sin embargo, cuando el valor asignado es una Array , una Function o un Object , se asigna una referencia al objeto en la memoria .

Tiempo de ejemplo! En el siguiente fragmento, var2 se establece como igual a var1 . Dado que var1 es un tipo primitivo ( String ), var2 se establece como igual al valor String de var1 y se puede considerar como completamente distinto de var1 en este punto. En consecuencia, la reasignación de var2 no tiene efecto en var1.


let var1 = 'Mi cadena';let var2 = var1;

var2 = 'Mi nueva cadena';




console.log(var1);// 'Mi cadena'console.log(var2);// 'Mi nueva cadena'

Comparemos esto con la asignación de objetos.


let var1 = { nombre: 'Jim' }let var2 = var1;

var2.nombre = 'Juan';




consola.log(var1);// { nombre: 'Juan' }console.log(var2);// { nombre: 'Juan' }

¡Uno podría ver cómo esto podría causar problemas si esperaba un comportamiento como una asignación primitiva! Esto puede ponerse especialmente feo si crea una función que muta involuntariamente un objeto.

2. Cierres

El cierre es un patrón de JavaScript importante para dar acceso privado a una variable. En este ejemplo, createGreeter devuelve una función anónima que tiene acceso al greeting proporcionado, "Hola". Para todos los usos futuros, sayHello tendrá acceso a este saludo.





function createGreeter(saludo) {return función(nombre) {console.log(saludo + ', ' + nombre);}}



const decirHola = createGreeter('Hola');decirHola('Joe');// Hola, Joe

En un escenario más real, podría imaginar una función inicial apiConnect(apiKey) que devuelve algunos métodos que usarían la clave API. En este caso, la apiKey solo tendría que proporcionarse una vez y nunca más.




function apiConnect(apiKey) {function get(ruta) {return fetch(`${ruta}?key=${apiKey}`);}



function post(ruta, parámetros) {return fetch(ruta, { method: 'POST', body: JSON.stringify(params), headers: { 'Authorization': `Bearer ${apiKey}` } } )}


volver {obtener, publicar}}

const api = apiConnect('mi-clave-secreta');



// Ya no es necesario incluir apiKeyapi.get('http://www.example.com/get-endpoint');api.post('http://www.example.com/post-endpoint', { nombre: 'Joe' });

3. Desestructuración

¡No se deje intimidar por la desestructuración de parámetros de JavaScript! Es una forma común de extraer limpiamente las propiedades de los objetos.




const obj = {nombre: 'Joe',comida: 'pastel'}

const { nombre, alimento } = obj;


console.log(nombre, comida);// 'Joe' 'pastel'

Si desea extraer propiedades con un nombre diferente, puede especificarlas usando el siguiente formato.




const obj = {nombre: 'Joe',comida: 'pastel'}

const { nombre: miNombre, comida: miComida } = obj;


console.log(miNombre, miComida);// 'Joe' 'pastel'

En el siguiente ejemplo, se utiliza la desestructuración para pasar limpiamente el objeto person a la función de introduce . En otras palabras, la desestructuración puede usarse (y a menudo se usa) directamente para extraer parámetros pasados a una función. Si está familiarizado con React, ¡probablemente haya visto esto antes!




persona constante = {nombre: 'Eddie', edad: 24}



función presentar ({nombre, edad}) {console.log(`Soy ${nombre} y tengo ${edad} años!`);}


console.log(presente(persona));// "¡Soy Eddie y tengo 24 años!"

4. Sintaxis extendida

¡Un concepto de JavaScript que puede desconcertar a la gente pero que es relativamente simple es el operador de propagación! En el siguiente caso, Math.max no se puede aplicar a la matriz arr porque no toma una matriz como argumento, toma los elementos individuales como argumentos. El operador de propagación ... se utiliza para sacar los elementos individuales de la matriz.




const arr = [4, 6, -1, 3, 10, 4];const max = Math.max(...arr);console.log(max);// 10

5. Resto de sintaxis

Hablemos de la sintaxis de descanso de JavaScript. ¡Puede usarlo para poner cualquier número de argumentos pasados a una función en una matriz!



function myFunc(...argumentos) {console.log(argumentos[0] + argumentos[1]);}


miFunc(1, 2, 3, 4);// 3

6. Métodos de matriz

Los métodos de matriz de JavaScript a menudo pueden proporcionarle formas increíbles y elegantes de realizar la transformación de datos que necesita. Como colaborador de StackOverflow, con frecuencia veo preguntas sobre cómo manipular una matriz de objetos de una forma u otra. Este tiende a ser el caso de uso perfecto para los métodos de matriz.

Cubriré una serie de métodos de matriz diferentes aquí, organizados por métodos similares que a veces se combinan. Esta lista no es exhaustiva: lo animo a revisar y practicar todos los discutidos en MDN (mi referencia de JavaScript favorita).


** mapear, filtrar, reducir ** Existe cierta confusión en torno a los métodos de matriz de JavaScript map , filter , reduce . Estos son métodos útiles para transformar una matriz o devolver un valor agregado.

  • mapa: matriz de retorno donde cada elemento se transforma según lo especificado por la función


const arr = [1, 2, 3, 4, 5, 6];const mapeado = arr.map(el => el + 20);


console.log(asignado);// [21, 22, 23, 24, 25, 26]

  • filtro: devuelve una matriz de elementos donde la función devuelve verdadero


const arr = [1, 2, 3, 4, 5, 6];const filtered = arr.filter(el => el === 2 || el === 4);


console.log(filtrado);// [2, 4]

  • reducir: acumular valores como se especifica en la función


const arr = [1, 2, 3, 4, 5, 6];const reducido = arr.reduce((total, actual) => total + actual);


console.log(reducido);// 21


**find, findIndex, indexOf**Los métodos de matriz find , findIndex e indexOf a menudo se pueden combinar. Úselos de la siguiente manera.

  • find : devuelve la primera instancia que coincide con los criterios especificados. No avanza para encontrar otras instancias coincidentes.


const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];const encontrado = arr.find(el => el > 5);


consola.log(encontrado);// 6

Nuevamente, tenga en cuenta que si bien todo lo que está después 5 cumple con los criterios, solo se devuelve el primer elemento coincidente. ¡Esto es realmente muy útil en situaciones en las que normalmente break un bucle for cuando encuentras una coincidencia!

  • findIndex : esto funciona de manera casi idéntica a find , pero en lugar de devolver el primer elemento coincidente, devuelve el índice del primer elemento coincidente. Tome el siguiente ejemplo, que usa nombres en lugar de números para mayor claridad.


const arr = ['Nick', 'Frank', 'Joe', 'Frank'];const foundIndex = arr.findIndex(el => el === 'Frank');


consola.log(índice encontrado);// 1

  • indexOf: funciona de manera casi idéntica a findIndex , pero en lugar de tomar una función como argumento, toma un valor simple. Puede usar esto cuando tiene una lógica más simple y no necesita usar una función para verificar si hay una coincidencia.


const arr = ['Nick', 'Frank', 'Joe', 'Frank'];const foundIndex = arr.indexOf('Frank');


consola.log(índice encontrado);// 1


**push, pop, shift, unshift** Hay una gran cantidad de excelentes métodos de matriz para ayudar a agregar o eliminar elementos de las matrices de manera específica.

  • push: este es un método relativamente simple que agrega un elemento al final de una matriz. Modifica la matriz en el lugar y la función en sí misma devuelve el elemento agregado a la matriz.


let arr = [1, 2, 3, 4];const empujado = arr.push(5);




console.log(arr);// [1, 2, 3, 4, 5]console.log(empujado);// 5

  • pop: esto elimina el último elemento de una matriz. Nuevamente, modifica la matriz en su lugar. La función en sí devuelve el elemento eliminado de la matriz.


let arr = [1, 2, 3, 4];const popped = arr.pop();




console.log(arr);// [1, 2, 3]console.log(aparecido);// 4

  • shift: esto elimina el primer elemento de una matriz. Nuevamente, modifica la matriz en su lugar. La función en sí devuelve el elemento eliminado de la matriz.


let arr = [1, 2, 3, 4];const shifted = arr.shift();




consola.log(arr);// [2, 3, 4]console.log(cambiado);// 1

  • unshift: esto agrega uno o más elementos al comienzo de una matriz. Nuevamente, modifica la matriz en su lugar. A diferencia de muchos de los otros métodos, la función en sí devuelve la nueva longitud de la matriz.


let arr = [1, 2, 3, 4];const unshifted = arr.unshift(5, 6, 7);




console.log(arr);// [5, 6, 7, 1, 2, 3, 4]console.log(sin cambios);// 7


**empalme, corte**Estos métodos modifican o devuelven subconjuntos de matrices.

  • empalme: cambie el contenido de una matriz eliminando o reemplazando elementos existentes y/o agregando nuevos elementos. Este método modifica la matriz en su lugar.

El siguiente ejemplo de código se puede leer como: en la posición 1 de la matriz, elimine 0 elementos e inserte b .


let arr = ['a', 'c', 'd', 'e'];arr.splice(1, 0, 'b')

  • rebanada: devuelve una copia superficial de una matriz desde una posición de inicio especificada y antes de una posición final especificada. Si no se especifica una posición final, se devuelve el resto de la matriz. Es importante destacar que este método no modifica la matriz en su lugar, sino que devuelve el subconjunto deseado.


let arr = ['a', 'b', 'c', 'd', 'e'];const rebanada = arr.slice(2, 4);




consola.log(cortado);// ['c', 'd']console.log(arr);// ['a', 'b', 'c', 'd', 'e']

clasificar

  • ordenar: ordena una matriz en función de la función proporcionada que toma un argumento del primer elemento y del segundo elemento. Modifica la matriz en su lugar. Si la función devuelve negativo o 0, el orden permanece sin cambios. Si es positivo, se cambia el orden de los elementos.



let arr = [1, 7, 3, -1, 5, 7, 2];const sorter = (firstEl, secondEl) => firstEl - secondEl;arr.sort(sorter);


consola.log(arr);// [-1, 1, 2, 3, 5, 7, 7]

Uf, ¿captaste todo eso? Yo tampoco. De hecho, tuve que consultar mucho los documentos de MDN mientras escribía esto, ¡y está bien! El simple hecho de saber qué tipo de métodos existen te lleva al 95% del camino.

7. Generadores

No temas el * . La función del generador especifica qué value se obtiene la próxima vez que se llama a next() . Puede tener un número finito de rendimientos, después de lo cual next() devuelve un value indefinido, o un número infinito de valores mediante un bucle.





function* saludador() {yield 'Hola';yield '¿Cómo estás?';yield 'Adiós';}

const saludo = saludador();








console.log(saludar.siguiente().valor);// 'Hola'console.log(saludar.siguiente().valor);// '¿Cómo estás?'console.log(saludar.siguiente().valor );// 'Adiós'console.log(saludo.siguiente().valor);// indefinido

Y usando un generador para valores infinitos:





function* idCreator() {let i = 0;while (true)yield i++;}

const ids = idCreator();







console.log(ids.next().value);// 0console.log(ids.next().value);// 1console.log(ids.next().value);// 2// etc. ..

8. Operador de Identidad ( === ) vs. Operador de Igualdad ( == )

¡Asegúrese de conocer la diferencia entre el operador de identificación ( === ) y el operador de igualdad ( == ) en JavaScript! El operador == realizará la conversión de tipo antes de comparar valores, mientras que el operador === no realizará ninguna conversión de tipo antes de comparar.




consola.log(0 == '0');// trueconsole.log(0 === '0');// falso

9. Comparación de objetos

Un error que veo que cometen los recién llegados a JavaScript es comparar objetos directamente. ¡Las variables apuntan a referencias a los objetos en la memoria, no a los objetos mismos! Un método para compararlos realmente es convertir los objetos en cadenas JSON. Sin embargo, esto tiene un inconveniente: ¡el orden de las propiedades de los objetos no está garantizado! Una forma más segura de comparar objetos es obtener una biblioteca que se especialice en la comparación profunda de objetos (por ejemplo, isEqual de lodash ).

Los siguientes objetos parecen iguales, pero de hecho apuntan a diferentes referencias.


const joe1 = { nombre: 'Joe' }; const joe2 = { nombre: 'Joe' };


consola.log(joe1 === joe2);// falso

Por el contrario, lo siguiente se evalúa como verdadero porque un objeto se establece igual que el otro objeto y, por lo tanto, apunta a la misma referencia (solo hay un objeto en la memoria).


const joe1 = { nombre: 'Joe' };const joe2 = joe1;


consola.log(joe1 === joe2);// verdadero

¡Asegúrese de revisar la sección Valor versus referencia anterior para comprender completamente las ramificaciones de establecer una variable igual a otra variable que apunta a una referencia a un objeto en la memoria!

10. Funciones de devolución de llamada

¡Demasiadas personas se sienten intimidadas por las funciones de devolución de llamada de JavaScript! Son simples, toma este ejemplo. La función console.log se pasa como devolución de llamada a myFunc . Se ejecuta cuando se completa setTimeout . ¡Eso es todo al respecto!





function myFunc(texto, devolución de llamada) {setTimeout(función() {devolución de llamada(texto);}, 2000);}


myFunc('¡Hola mundo!', console.log);// '¡Hola mundo!'

11. Promesas

Una vez que comprenda las devoluciones de llamada de JavaScript, pronto se encontrará en un "infierno de devolución de llamada" anidado. ¡Aquí es donde Promises ayuda! Envuelva su lógica asíncrona en una Promesa y resolve si tiene éxito o reject si falla. Use "then" para manejar el éxito y catch para manejar el fracaso.








const myPromise = new Promise(function(res, rej) {setTimeout(function(){if (Math.random() < 0.9) {return res('¡Hurra!');}return rej('¡Oh, no!'); }, 1000);});







myPromise.then(función(datos) {console.log('Éxito: ' + datos);}).catch(función(err) {console.log('Error: ' + err);});




// Si Math.random() devuelve menos de 0,9, se registra lo siguiente: // "Éxito: ¡Hurra!"// Si Math.random() devuelve 0,9 o más, se registra lo siguiente: // "Error: ¡No! "

12. Espera asíncrona

Una vez que aprenda las promesas de JavaScript, es posible que le guste async await , que es simplemente "azúcar sintáctico" además de las promesas. En el siguiente ejemplo, creamos una función async y dentro de ella await la promesa de greeter .



const saludador = new Promise((res, rej) => {setTimeout(() => res('¡Hola mundo!'), 2000);})




función asíncrona myFunc() {const saludo = esperar saludo;console.log(saludo);}


myFunc();// '¡Hola mundo!'

Conclusión

Si no conocía ninguno de estos 12 conceptos, es probable que haya crecido al menos un poco en su conocimiento de JavaScript. Y si los conocía a todos, espero que esta sea una oportunidad para practicar y aumentar su conocimiento. ¿Qué otros conceptos crees que son críticos? Házmelo saber en los comentarios.