<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Kelvin Sanchez - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Descubre miles de cursos de programación escritos por expertos. Aprende Desarrollo Web, Ciencia de Datos, DevOps, Seguridad y obtén asesoramiento profesional para desarrolladores. ]]>
        </description>
        <link>https://www.freecodecamp.org/espanol/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Kelvin Sanchez - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/espanol/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 31 May 2026 04:47:24 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/espanol/news/author/kelvin/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Cómo agregar una imagen social a tu repositorio en GitHub ]]>
                </title>
                <description>
                    <![CDATA[ Compartir enlaces sin una imagen social puede convertir un contenido poderoso en un fracaso. ¿Cómo podemos aprovechar al máximo los beneficios que nos brindan las redes sociales cuando compartimos nuestro arduo trabajo en GitHub? ¿Quieres omitir el "qué" y el "por qué"? ¡Salta directo al "cómo"! El impacto de las ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-agregar-una-imagen-de-red-social-a-tu-repositorio-en-github/</link>
                <guid isPermaLink="false">5ffda95f8c7cd154bb98670d</guid>
                
                    <category>
                        <![CDATA[ Programación ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Wed, 03 Mar 2021 05:54:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/01/--C-mo.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Compartir enlaces sin una imagen social puede convertir un contenido poderoso en un fracaso. ¿Cómo podemos aprovechar al máximo los beneficios que nos brindan las redes sociales cuando compartimos nuestro arduo trabajo en GitHub?</p><p>¿Quieres omitir el "qué" y el "por qué"? <a href="#agregar-una-imagen-a-tu-repositorio-de-github">¡Salta directo al "cómo"!</a></p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.25%;" class="fluid-width-video-wrapper">
            <iframe src="https://www.youtube.com/embed/KRNiqCLlPNQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" name="fitvid0" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: absolute; top: 0px; left: 0px; width: 840px; height: 472.5px;"></iframe>
          </div>
        </div>
      </figure><h2 id="el-impacto-de-las-im-genes-en-las-redes-sociales">El impacto de las imágenes en las redes sociales</h2><p>Cualquier feed de red social es una ráfaga de contenido que puede ser difícil de digerir por completo. A medida que deslizas o te desplazas a través de los feeds, te encontrarás con contenido basado en texto y otros diferentes medios.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/02/twitter-feed-media-1.jpg" class="kg-image" alt="twitter-feed-media-1" width="600" height="400" loading="lazy"><figcaption>Feeds en Twitter usando TweetDeck</figcaption></figure><p>¡Y esto es por una buena razón! Al analizar el ejemplo anterior, ¿qué se destaca? No el <a href="https://twitter.com/uiswarup/status/1230781530907324417">retweet sobre Dust Particle</a> de <a href="https://twitter.com/CodePen">CodePen</a> a la izquierda, sino el de AWS en el medio, la nariz de perro en la parte superior izquierda y Al Pacino en la parte superior derecha entre las otras publicaciones mediáticas grandes.</p><p>Las imágenes, los gifs y los videos son una buena forma de proporcionar contenido llamativo. Como beneficio adicional, por lo general ocupan mucho más espacio en el feed, por lo que es aún más probable que tengas la oportunidad de verlo.</p><h2 id="lo-m-nimo-en-github"><strong><strong><strong><strong><strong>Lo mínimo en Git</strong></strong>H<strong><strong>ub</strong></strong></strong></strong></strong></h2><p>Al compartir tus proyectos de GitHub en las redes sociales, la opción predeterminada es bastante insulsa. Toma este tweet como ejemplo:</p><figure class="kg-card kg-embed-card"><iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="" title="Twitter Tweet" src="https://platform.twitter.com/embed/index.html?creatorScreenName=colbyfayock&amp;dnt=false&amp;embedId=twitter-widget-0&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=1226204581824204804&amp;lang=en&amp;origin=https%3A%2F%2Fwww.freecodecamp.org%2Fnews%2Fhow-to-add-a-social-media-image-to-your-github-project%2F&amp;siteScreenName=freecodecamp&amp;theme=light&amp;widgetsVersion=ed20a2b%3A1601588405575&amp;width=550px" data-tweet-id="1226204581824204804" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: static; visibility: visible; width: 550px; height: 322px; display: block; flex-grow: 1;" loading="lazy"></iframe></figure><p>GitHub nos brinda una simple <a href="https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards">tarjeta de redes sociales</a> que consta de nuestro avatar de GitHub, la ruta de nuestro proyecto y una breve descripción de la parte superior de la página.</p><p>Ahora, es genial que al menos muestren una tarjeta, y para ser justos, ¿Que más podrían mostrar?. Pero este tweet se saltará con bastante facilidad en los feeds de las personas entre las imágenes más grandes y llamativas.</p><h2 id="im-genes-de-red-social-en-github"><strong>Imágenes de red social en GitHub</strong></h2><p>Afortunadamente, GitHub nos provee una forma fácil de agregar una imagen a cada repositorio que puede ayudar a que el contenido que compartamos funcione de mejor manera.</p><p>Con un poco de creatividad, podemos subir una imagen que aprovechará el espacio en los feeds de las personas y conseguirá que tu trabajo reciba la atención que se merece.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/02/canva-social-media-example-2.jpg" class="kg-image" alt="canva-social-media-example-2" width="600" height="400" loading="lazy"><figcaption>Ejemplo de una imagen social usando Canva</figcaption></figure><p>Antes de entrar en detalle, debes saber que para cambiar la imagen del repositorio es necesario tener el acceso adecuado a la configuración del mismo. Si creaste el repositorio, lo más probable es que tengas este acceso.</p><h2 id="buscar-o-crear-una-imagen"><strong><strong><strong>Buscar<strong><strong> o crear una imagen</strong></strong></strong></strong></strong></h2><p>Antes de cargar una imagen, necesitamos una imagen en primer lugar. Puedes escoger una de estas dos alternativas: buscar una imagen o crear una nueva.</p><p>Si escoges la alternativa simple, puedes buscar imágenes gratuitas para usar, son bastante fáciles de encontrar en la web. Uno de mis sitios favoritos es <a href="https://unsplash.com/">Unsplash</a>, ya que normalmente encontrarás imágenes de alta calidad, pero hay un montón de otras que puedes encontrar con <a href="https://www.google.com/search?q=free+stock+photos">una simple búsqueda</a>. Sin embargo, agregar fotos suele ser mejor para publicaciones de blog y publicaciones basadas en contenido.</p><figure class="kg-card kg-embed-card"><iframe id="twitter-widget-1" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="" title="Twitter Tweet" src="https://platform.twitter.com/embed/index.html?creatorScreenName=colbyfayock&amp;dnt=false&amp;embedId=twitter-widget-1&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=1230190815605121024&amp;lang=en&amp;origin=https%3A%2F%2Fwww.freecodecamp.org%2Fnews%2Fhow-to-add-a-social-media-image-to-your-github-project%2F&amp;siteScreenName=freecodecamp&amp;theme=light&amp;widgetsVersion=ed20a2b%3A1601588405575&amp;width=550px" data-tweet-id="1230190815605121024" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: static; visibility: visible; width: 550px; height: 654px; display: block; flex-grow: 1;" loading="lazy"></iframe></figure><p>La mejor alternativa es crear la tuya propia. Una ventaja de crear una imagen es que puedes personalizarla con un texto más grande para captar más atención en el feed.</p><p>Hay un <a href="https://zapier.com/blog/graphic-design-tools-for-social-media-images/">montón de herramientas gratuitas</a> disponibles que te permiten crear una imagen comenzando con una plantilla específica para redes sociales, por lo que no necesitas gastar dinero en <a href="https://www.adobe.com/products/photoshopfamily.html">Photoshop</a> para lograrlo.</p><p>El único requisito para tu imagen es que su tamaño debe ser de al menos 640×320px. De ser posible, céntrate en obtener al menos 1280×640px para asegurarte de que la imagen se muestre en alta resolución en los feeds.</p><h2 id="agregar-una-imagen-a-tu-repositorio-de-github"><strong>Agregar una imagen a tu repositorio de Github</strong></h2><p>Una vez que tenemos nuestra imagen, solo nos queda agregarla a nuestro repositorio, que posiblemente sea la parte más simple.</p><p>Primero, navega a la configuración (settings) de tu repositorio usando la pestaña de navegación en la parte superior de la página. Como recordatorio, debes poder modificar la configuración para cambiar la imagen.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/02/github-settings-page-1.jpg" class="kg-image" alt="github-settings-page-1" width="600" height="400" loading="lazy"><figcaption>Página de configuración de GitHub</figcaption></figure><p>A continuación, desplaza hacia abajo hasta la sección vista previa <em>Social (Social preview), </em> donde si actualmente no tienes ninguna imagen, encontrarás un gran rectángulo vacío con el botón <em>Edit</em> (Editar) en la esquina inferior izquierda.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/02/github-upload-social-image.jpg" class="kg-image" alt="github-upload-social-image" width="600" height="400" loading="lazy"><figcaption>Subir imagen social en GitHub</figcaption></figure><p>Has clic en el botón <em>Edit</em> (Editar), selecciona <em>Upload an image</em> (Cargar una imagen), luego busca la imagen en tu ordenador y selecciona el archivo.</p><p>Una vez seleccionado, el archivo de imagen se cargará en GitHub y se establecerá como imagen social del repositorio.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/news/content/images/2020/02/github-social-media-image.jpg" class="kg-image" alt="github-social-media-image" width="600" height="400" loading="lazy"><figcaption>Vista previa de imagen social en GitHub</figcaption></figure><h2 id="pre-visualizar-tu-nueva-imagen"><strong>Pre-visualizar tu nueva imagen</strong></h2><p>Cuando hayas terminado de cargar tu imagen, puedes dirigirte a tu plataforma social favorita y probarla. Por ejemplo, al publicar en Twitter, se mostrará una bonita y grande imagen en lugar de tu pequeño avatar de GitHub.</p><figure class="kg-card kg-embed-card"><iframe id="twitter-widget-2" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="" title="Twitter Tweet" src="https://platform.twitter.com/embed/index.html?creatorScreenName=colbyfayock&amp;dnt=false&amp;embedId=twitter-widget-2&amp;frame=false&amp;hideCard=false&amp;hideThread=false&amp;id=1230604806324183046&amp;lang=en&amp;origin=https%3A%2F%2Fwww.freecodecamp.org%2Fnews%2Fhow-to-add-a-social-media-image-to-your-github-project%2F&amp;siteScreenName=freecodecamp&amp;theme=light&amp;widgetsVersion=ed20a2b%3A1601588405575&amp;width=550px" data-tweet-id="1230604806324183046" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-size: 22px; vertical-align: middle; position: static; visibility: visible; width: 550px; height: 580px; display: block; flex-grow: 1;" loading="lazy"></iframe></figure><p>Como puedes ver, este tweet maximiza el espacio disponible y hace entender de qué se trata el proyecto.</p><h2 id="algunos-consejos-al-crear-im-genes"><strong><strong><strong><strong><strong>Algunos consejos al crear imágenes</strong></strong></strong></strong></strong></h2><h3 id="texto-grande-y-sencillo"><strong><strong><strong><strong><strong>Texto grande y sencillo</strong></strong></strong></strong></strong></h3><p>Puede ser fácil quedarse atrapado sobre-diseñando un gráfico en exceso o no prestar suficiente atención al tamaño de la fuente. Asegúrate de usar letras grandes con una fuente que sea fácil de leer, de modo que cuando alguien se desplace sobre tu publicación, pueda entenderla y no simplemente omitirla.</p><h3 id="agregar-un-logo"><strong><strong><strong><strong><strong>Agregar un logo</strong></strong></strong></strong></strong></h3><p>¿Tienes un logo para tu proyecto? ¿O es un complemento para una herramienta específica? ¡Intenta agregar un logotipo para dar contexto de inmediato sobre el tema del proyecto!</p><h3 id="maximizar-la-resoluci-n"><strong><strong><strong><strong><strong>Maximizar la resolución</strong></strong></strong></strong></strong></h3><p>A nadie le gusta mirar imágenes de mala calidad. Aprovecha todos esos valiosos píxeles y carga una imagen que se traduzca con alta calidad en cualquier feed. GitHub recomienda particularmente un tamaño de imagen de al menos 1280×640px.</p><h2 id="-tienes-otros-trucos-para-maximizar-el-intercambio-en-las-redes-sociales"><strong><strong><strong><strong><strong>¿Tiene</strong></strong>s<strong><strong> otros trucos para maximizar el intercambio en las redes sociales?</strong></strong></strong></strong></strong></h2><p>¡Comparte tus consejos favoritos conmigo en <a href="https://twitter.com/colbyfayock">Twitter</a> !</p><figure class="kg-card kg-image-card"><img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" class="kg-image" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy"></figure><ul><li><a href="https://twitter.com/colbyfayock">? Sigueme en Twitter</a></li><li><a href="https://youtube.com/colbyfayock">? ️ Suscríbete a mi Youtube</a></li><li><a href="https://www.colbyfayock.com/newsletter/">✉️ Suscríbete a mi boletín</a></li></ul><p>Traducido del artículo de <a href="https://www.freecodecamp.org/news/author/colbyfayock/"><strong>Colby Fayock</strong></a><strong><strong> - </strong><a href="https://www.freecodecamp.org/news/how-to-add-a-social-media-image-to-your-github-project/">How to Add a Social Media Image to Your Github Project Repository</a></strong>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo utilizar la Interpolación de Cadenas en JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ La adición de las plantillas literales en ECMAScript 6 (ES6) nos permite interpolar cadenas en JavaScript. En palabras más simples, podemos usar marcadores de posición para inyectar variables en una cadena. Puedes ver un ejemplo de interpolación de cadena utilizando plantillas literales en el siguiente código: const edad = 4.5; ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-utilizar-la-interpolacion-de-cadenas-en-javascript/</link>
                <guid isPermaLink="false">5ff4b42f8c7cd154bb984bdf</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Fri, 19 Feb 2021 04:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/04/photo-1528341727508-3814ebdd9122.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>La adición de las plantillas literales en ECMAScript 6 (ES6) nos permite interpolar cadenas en JavaScript.</p><p>En palabras más simples, podemos usar marcadores de posición para inyectar variables en una cadena. Puedes ver un ejemplo de interpolación de cadena utilizando plantillas literales en el siguiente código:</p><pre><code class="language-js">const edad = 4.5;
const edadTierra = `Se estima que la Tierra tiene ${edad} mil millones de años.`;

console.log(edadTierra);
</code></pre><p>En primer lugar, puedes ver que estamos usando comillas invertidas <code>``</code> para crear las plantillas literales. El formato <code>${marcador}</code> nos permite insertar un valor dinámico en la cadena. Todo lo que hay dentro <code>${}</code> es evaluado como JavaScript.</p><p>Por ejemplo, podríamos escribir <code>Se estima que la Tierra tiene ${edad + 10} mil millones de años.</code>, y funcionaría como si hiciéramos <code>const edad = 4.5 + 10;</code>. </p><h3 id="-c-mo-lo-hac-amos-antes"><strong>¿Cómo lo hacíamos antes?</strong></h3><p>Antes de contar con las plantillas literales, lo habríamos hecho de la siguiente manera:</p><pre><code class="language-js">const edadTierra = "Se estima que la Tierra tiene " + edad + " mil millones de años.";
</code></pre><p>Como puedes ver, se utilizan demasiadas comillas para una simple cadena. Imagina que tengamos que insertar múltiples variables. Puede transformarse rápidamente en una cadena compleja que no es muy legible. Por lo tanto, las plantillas literales hacen que las cadenas sean más limpias y legibles.</p><p>Sin embargo, este es solo un caso. Veamos más casos de uso para las plantillas literales.</p><h2 id="cadenas-multil-nea"><strong>Cadenas multilínea</strong></h2><p>Otro caso de utilidad para las plantillas literales son las cadenas multilínea. Antes usábamos <code>\n</code> para expresar nuevas líneas, como por ejemplo: <code>console.log('línea 1\n' + 'línea 2')</code>.</p><p>Para dos líneas esto podría estar bien. Pero imagina que queremos cinco líneas. Una vez más, la cadena se vuelve innecesariamente compleja.</p><pre><code class="language-js">const edadTierra = `Se estima que la Tierra tiene ${edad} mil millones de años.

Los científicos han rastreado la Tierra en busca de las rocas más antiguas para precisar fechas radiométricamente.

En el noroeste de Canadá, descubrieron rocas de unos 4.030 millones de años.
`;</code></pre><p>El fragmento anterior demuestra una vez más lo sencillo y limpio que se vuelve escribir cadenas multilínea con plantillas literales.</p><p>Como ejercicio, intenta convertir la cadena anterior usando concatenación y saltos de línea <code>\n</code>.</p><h2 id="expresiones"><strong>Expresiones</strong></h2><p>Con las plantillas literales también podemos usar expresiones dentro de las cadenas. ¿Qué significa eso?</p><p>Por ejemplo, podríamos usar expresiones matemáticas como la multiplicación de dos números. El fragmento a continuación ilustra esto:</p><pre><code class="language-js">const primerNumero = 10;
const segundoNumero = 39;
const resultado = `El resultado de multiplicar ${primerNumero} por ${segundoNumero} es ${primerNumero * segundoNumero}.`;

console.log(resultado);</code></pre><p>Sin las plantillas literales tendríamos que hacer algo como esto:</p><pre><code class="language-js">const resultado = "El resultado de multiplicar " + primerNumero + " por " + segundoNumero + " es " + primerNumero * segundoNumero + ".";
</code></pre><p>Escribir una cadena como la anterior puede volverse rápidamente complejo y confuso. Como seguimos viendo, las plantillas literales facilitan y hacen más elegante incrustar expresiones en la cadena.</p><h2 id="operador-ternario"><strong>Operador ternario</strong></h2><p>Con la interpolación de cadenas incluso podemos usar un operador ternario dentro de una cadena. Esto nos permite verificar el valor de una variable y mostrar diferentes cosas dependiendo de ese valor.</p><p>Veamos el siguiente ejemplo:</p><pre><code class="language-js">const bebidas = 4.99;
const comida = 6.65;
const total = bebidas + comida;

const resultado = `El total de la factura es ${total}. ${total &gt; 10 ? `Su pago con tarjeta será rechazado` : `Su pago con tarjeta será aceptado`}.`

console.log(resultado);</code></pre><p>En el código anterior verificamos si el monto total es superior a diez dólares. Si el importe es superior a diez, avisamos al usuario que se rechazará el pago con tarjeta. De lo contrario, se acepta el pago con tarjeta.</p><p>Como puedes ver, la interpolación nos permite hacer cosas interesantes con las cadenas.</p><h1 id="conclusi-n"><strong>Conclusión</strong></h1><p>La adición plantillas literales en ES6 nos permite escribir cadenas mejores, más cortas y claras. También nos da la capacidad de inyectar variables y expresiones en cualquier cadena. Esencialmente, todo lo que escriba dentro de las llaves (<code>${}</code>) se evaluará como JavaScript.</p><p>Por lo tanto, podemos usar plantillas literales para:</p><ul><li>Escribir cadenas multilínea</li><li>Incrustar expresiones</li><li>Escribir cadenas con el operador ternario</li></ul><p><em><em><em><em>Si </em></em>te<em><em> gusta lo que escribo, es probable que </em></em>t<em><em>e encante lo que envío por correo electrónico. Consider</em></em>a<em><em> suscribir</em></em>t<em><em>e a mi</em></em></em> <a href="https://landing.mailerlite.com/webforms/landing/i4b6v1">boletín</a><em><em><em>. Si no e</em></em>re<em><em>s</em></em> fanático de los boletines<em><em>, siempre podemos mantener</em></em> el<em><em> contacto </em></em></em>vía<em><em><em> <strong><strong><strong><strong><a href="https://twitter.com/intent/follow?screen_name=catalinmpit">Twitter</a></strong></strong></strong></strong>.</em></em></em></em></p><p>Traducido del artículo de <strong><a href="https://www.freecodecamp.org/news/author/catalin/"><strong>Catalin Pit</strong></a><strong> - </strong><a href="https://www.freecodecamp.org/news/javascript-string-format-how-to-use-string-interpolation-in-js/">JavaScript String Format – How to use String Interpolation in JS</a>.</strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo utilizar la Desestructuración de Arreglos y Objetos en JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ La sintaxis de desestructuración es una funcionalidad fascinante que vino junto con ES6. Es una expresión de JavaScript que permite desempacar valores de arreglos o propiedades de objetos en distintas variables. Es decir, podemos extraer datos de arreglos y objectos y asignarlos a variables. ¿Por qué es esto necesario? Imagina ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/desestructuracion-de-arreglos-y-objetos-en-javascript/</link>
                <guid isPermaLink="false">5fea37848c7cd154bb980e37</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Fri, 29 Jan 2021 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/04/photo-1551641145-a1e18544acb9-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>La sintaxis de desestructuración es una funcionalidad fascinante que vino junto con ES6. Es una expresión de JavaScript que permite desempacar valores de arreglos o propiedades de objetos en distintas variables. Es decir, podemos extraer datos de arreglos y objectos y asignarlos a variables.</p><p>¿Por qué es esto necesario?</p><p>Imagina que queremos extraer datos de un arreglo. Anteriormente, ¿cómo se haría esto?</p><pre><code class="language-javascript">let introduccion = ["Hola", "Yo" , "soy", "Sarah"];
let saludo = introduccion[0];
let nombre = introduccion[3];

console.log(saludo); // "Hola"
console.log(nombre); // "Sarah"
</code></pre><p>Podemos ver que cuando queremos extraer datos de un arreglo, tenemos que hacer lo mismo una y otra vez.</p><p>La desestructuración de ES6 facilita la extracción de estos datos. ¿De qué forma? Primero, discutiremos sobre la desestructuración con arreglos. Luego pasaremos a la desestructuración de objetos.</p><p>Empecemos.</p><h2 id="desestructuraci-n-b-sica-de-arreglos"><strong>Desestructuración Básica de Arreglos</strong></h2><p>Si queremos extraer datos de un arreglo, es bastante sencillo usando la sintaxis de desestructuración.</p><p>Tomando como referencia el primer ejemplo. En lugar de pasar por ese proceso repetitivo, haríamos esto:</p><pre><code class="language-javascript">let introduccion = ["Hola", "Yo" , "soy", "Sarah"];;
let [saludo, pronombre] = introduccion;

console.log(saludo); // "Hola"
console.log(pronombre); // "Yo"</code></pre><p>También podemos lo siguiente, y conseguir el mismo resultado:</p><pre><code class="language-javascript">let [saludo, pronombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(pronombre); // "Yo"</code></pre><h3 id="declarando-variables-antes-de-la-asignaci-n"><strong>Declarando Variables antes de la Asignación</strong></h3><p>Las variables se pueden declarar antes de ser asignadas de esta manera:</p><pre><code class="language-javascript">let saludo, pronombre;
[saludo, pronombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(pronombre); // "Yo"</code></pre><p>Observa que las variables se establecen de izquierda a derecha. Así que la primera variable obtiene el primer elemento del arreglo, la segunda variable obtiene el segundo elemento, y así sucesivamente.</p><h3 id="omitiendo-elementos-en-un-arreglo"><strong>Omitiendo elementos en un Arreglo</strong></h3><p>¿Qué pasa si queremos obtener el primer y último elemento de nuestro arreglo en lugar del primero y el segundo, y queremos asignar solo dos variables? Esto también se puede hacer. Fíjate en el siguiente ejemplo:</p><pre><code class="language-javascript">let [saludo,,,nombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(nombre); // "Sarah"</code></pre><p>¿Qué acaba de suceder?</p><p>Pon atención al lado izquierdo de la asignación de variables del arreglo. Observa que en lugar de tener solo una coma, tenemos tres. El separador de coma se utiliza para omitir valores en un arreglo. Por lo que, si deseas omitir un elemento en un arreglo, usa comas.</p><p>Veamos otro ejemplo. Si queremos saltar el primer y tercer elemento de la lista. ¿Cómo lo haríamos?</p><pre><code class="language-javascript">let [,pronombre,,nombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(pronombre); // "Yo"
console.log(nombre); // "Sarah"</code></pre><p>Como ves, el separador de comas es el que hace la magia. Entonces, si queremos omitir todos los elementos, simplemente hacemos esto:</p><pre><code class="language-javascript">let [,,,,] = ["Hola", "Yo" , "soy", "Sarah"];</code></pre><h3 id="asignando-el-resto-de-un-arreglo"><strong>Asignando el resto de un arreglo</strong></h3><p><br>¿Qué sucede si queremos asignar parte del arreglo a variables y el resto de elementos de dicho arreglo a otra variable en particular? En ese caso, haríamos esto:</p><pre><code class="language-javascript">let [saludo, ...introduccion] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(introduccion); // ["Yo", "soy", "Sarah"]</code></pre><p>Utilizando este patrón, puedes desempacar y asignar la parte restante de un arreglo a una variable.</p><h3 id="desestructuraci-n-con-funciones"><strong>Desestructuración con Funciones</strong></h3><p>También podemos extraer datos de un arreglo devuelto por una función. Digamos que tenemos una función que devuelve un arreglo como el del siguiente ejemplo:</p><pre><code class="language-javascript">function obtenerArreglo() {
    return ["Hola", "Yo" , "soy", "Sarah"];
} 

let [saludo, pronombre] = obtenerArreglo();

console.log(saludo); // "Hello"
console.log(pronombre); // "I"</code></pre><p>Como puedes observar, obtenemos los mismos resultados.</p><h3 id="usando-valores-predeterminados"><strong>Usando Valores Predeterminados</strong></h3><p>Los valores predeterminados se pueden asignar a las variables en caso de que el valor extraído del arreglo sea <code>undefined</code>:</p><pre><code class="language-javascript">let [saludo = "hey", nombre = "Sarah"] = ["Hola"];

console.log(greeting); // "Hola"
console.log(name); // "Sarah"
</code></pre><p>Por lo tanto, <code>nombre</code> se vuelve "Sarah" porque no está definido en el arreglo.</p><h3 id="intercambiando-valores-mediante-desestructuraci-n"><strong>Intercambiando Valores mediante Desestructuración</strong></h3><p>Una cosa más. Podemos usar la desestructuración para intercambiar los valores de las variables:</p><pre><code class="language-javascript">let a = 3;
let b = 6;

[a, b] = [b, a];

console.log(a); // 6
console.log(b); // 3</code></pre><p>A continuación, aprenderemos sobre la Desestructuración de Objetos.</p><h2 id="desestructuraci-n-de-objetos"><strong>Desestructuración de Objetos</strong></h2><p>Primero, veamos por qué es necesaria la desestructuración de objetos.</p><p>Digamos que queremos extraer datos de un objeto y asignarlos a nuevas variables. Antes de ES6, ¿cómo se haría esto?</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let nombre = persona.nombre;
let pais = persona.pais;
let trabajo = persona.trabajo;

console.log(nombre); // "Sarah"
console.log(pais); // "Nigeria"
console.log(trabajo); // "Desarrollador"</code></pre><p>Observa lo tedioso que es extraer todos los datos. Tenemos que hacer lo mismo repetidamente. Por suerte, la desestructuración de ES6 provee una solución. Saltemos directamente a ella.</p><h3 id="desestructuraci-n-b-sica-de-objetos"><strong>Desestructuración Básica de Objetos</strong></h3><p>Repitamos el ejemplo anterior con ES6. En lugar de asignar valores uno por uno, podemos usar el objeto de la izquierda para extraer los datos:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre, pais, trabajo} = persona;

console.log(nombre); // "Sarah"
console.log(pais); // "Nigeria"
console.log(trabajo); // "Desarrollador"
</code></pre><p>Obtendrás los mismos resultados. También es válido asignar variables a un objeto que no ha sido declarado:</p><pre><code class="language-javascript">let {nombre, pais, trabajo} = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

console.log(nombre); // "Sarah"
console.log(pais); // "Nigeria"
console.log(trabajo); // "Desarrollador"
</code></pre><h3 id="declarando-variables-antes-de-ser-asignadas"><strong>Declarando Variables antes de ser asignadas</strong></h3><p>Las variables en los objetos se pueden declarar antes de asignarlas con desestructuración. Probemos eso:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
}; 

let nombre, pais, trabajo;

{nombre, pais, trabajo} = persona;

console.log(nombre); // Error : "Unexpected token ="</code></pre><p>Espera, ¿qué acaba de pasar? Oh, nos olvidamos de agregar <code>()</code> antes de las llaves.</p><p>Los paréntesis &nbsp;<code>( )</code> alrededor de la asignación es una sintaxis requerida cuando se usa la desestructuración literal de un objeto sin una declaración. Esto se debe a que <code>{}</code> en el lado izquierdo se considera un bloque y no un objeto literal. Aquí te muestro la forma correcta de hacerlo:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
}; 

let nombre, pais, trabajo;

({nombre, pais, trabajo} = persona);

console.log(nombre); // "Sarah"
console.log(trabajo); // "Desarrollador"</code></pre><p>También es importante tener en cuenta que al usar esta sintaxis, los paréntesis <code>()</code> deben ir precedido de un punto y coma. De lo contrario, podría usarse para ejecutar una función de la línea anterior.</p><p>Observa como las variables del objeto en el lado izquierdo deben tener el mismo nombre que una clave de propiedad en el objeto <code>persona</code>. Si los nombres son diferentes, obtendremos <code>undefined</code>:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre, amigos, trabajo} = persona;

console.log(nombre); // "Sarah"
console.log(amigos); // undefined</code></pre><p>Pero si queremos usar un nuevo nombre de variable, bueno, también podemos hacerlo.</p><h3 id="usando-un-nuevo-nombre-de-variable"><strong>Usando un nuevo Nombre de Variable</strong></h3><p>Si queremos asignar valores de un objeto a una nueva variable en lugar de usar el nombre de la propiedad, podemos hacer esto:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre: foo, trabajo: bar} = persona;

console.log(foo); // "Sarah"
console.log(bar); // "Desarrollador"</code></pre><p>Entonces, los valores extraídos son pasados a las nuevas variables <code>foo</code> y <code>bar</code>.</p><h3 id="usando-valores-predeterminados-1"><strong>Usando Valores Predeterminados</strong></h3><p>Los valores predeterminados también se pueden usar en la desestructuración de objetos, en el caso de que una variable del objeto que se quiere extraer datos esté <code>undefined</code>:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre = "miNombre", amiga = "Annie"} = persona;

console.log(nombre); // "Sarah"
console.log(amiga); // "Annie"
</code></pre><p>Entonces, si el valor no es indefinido (undefined), la variable almacena el valor extraído del objeto como en el caso de <code>nombre</code>. De lo contrario, usará el valor predeterminado como lo hizo con <code>amiga</code>.</p><p>También podemos establecer valores predeterminados cuando asignamos valores a una nueva variable:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {name: foo = "miNombre", amiga: bar = "Annie"} = persona;

console.log(foo); // "Sarah"
console.log(bar); // "Annie"
</code></pre><p>Aquí <code>nombre</code> se extrajo de <code>persona</code> y se asignó a una variable diferente. <code>amiga</code>, por otro lado, estaba <code>undefined</code> en <code>persona</code>, por lo que a la nueva variable <code>bar</code> &nbsp;se le asignó el valor predeterminado.</p><h3 id="nombre-de-propiedad-calculado"><strong>Nombre de Propiedad Calculado</strong></h3><p>El nombre de propiedad calculado es otra funcionalidad de objectos literales que también funciona al desestructurar. Puedes especificar el nombre de una propiedad a través de una expresión si la pones entre corchetes:</p><pre><code class="language-javascript">let prop = "nombre";

let {[prop] : foo} = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

console.log(foo); // "Sarah"</code></pre><h3 id="combinando-arreglos-con-objetos">Combinando Arreglos con Objetos</h3><p>Las arreglos también se pueden usar con objetos en la desestructuración de objetos:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    amigas: ["Annie", "Becky"],
};

let {nombre: foo, amigas: bar} = persona;

console.log(foo); // "Sarah"
console.log(bar); // ["Annie", "Becky"]</code></pre><h3 id="anidamiento-en-la-desestructuraci-n-de-objetos"><strong>Anidamiento en la Desestructuración de Objetos</strong></h3><p>Los objetos también se pueden anidar al desestructurar:</p><pre><code class="language-javascript">let persona = {
    nombre: "Sarah",
    lugar: {
        pais: "Nigeria", 
        ciudad: "Lagos" 
    }, 
    amigas : ["Annie", "Becky"]
};

let {
  nombre: foo,
  lugar: { pais: bar, ciudad: x },
} = persona;

console.log(foo); // "Sarah"
console.log(bar); // "Nigeria"</code></pre><h3 id="resto-rest-en-la-desestructuraci-n-de-objetos"><strong>Resto (...rest) en la Desestructuración de Objetos</strong></h3><p>La sintaxis de resto también se puede utilizar para recopilar claves de propiedad que aún no han sido asignadas durante la desestructuración. Dichas claves y sus valores se copian en un nuevo objeto:</p><pre><code class="language-javascript">let persona = {
  nombre: "Sarah",
  pais: "Nigeria",
  trabajo: "Desarrollador",
  amigas: ["Annie", "Becky"],
};

let { nombre, amigas, ...otras } = persona;

console.log(nombre); // "Sarah"
console.log(amigas); // ["Annie", "Becky"]
console.log(otras); // {pais: "Nigeria", trabajo: "Desarrollador"}</code></pre><p>Aquí, las propiedades restantes cuyas claves no formaban parte de los nombres de variable enumerados se asignaron a la variable <code>otras</code>. La sintaxis de resto (rest) en el ejemplo es <code>...otras</code>. Cuyo nombre <code>otras</code> se puede cambiar por cualquiera de tu preferencia.</p><p>Una última cosa – veamos cómo se puede usar la Desestructuración de Objetos en funciones.</p><h3 id="desestructuraci-n-de-objetos-y-funciones"><strong>Desestructuración de Objetos y Funciones</strong></h3><p>La Desestructuración de Objetos se puede utilizar para asignar parámetros a funciones:</p><pre><code class="language-javascript">function persona({ nombre: x, trabajo: y } = {}) {
  console.log(x);
}

persona({ nombre: "Michelle" }); // "Michelle"
persona(); // undefined
persona(amiga); // Error : amiga is not defined</code></pre><p>Observa los <code>{}</code> en el lado derecho de los parámetros del objecto. Nos permite llamar a la función sin pasar ningún argumento. Por eso recibimos <code>undefined</code>. Si lo eliminamos, obtendremos un mensaje de error.</p><p>También podemos asignar valores predeterminados a los parámetros:</p><pre><code class="language-javascript">function person({ nombre: x = "Sarah", trabajo: y = "Desarrollador" } = {}) {
  console.log(x);
}

person({ nombre }); // "Sarah"</code></pre><p>Como hemos podido ver, se pueden hacer un montón de cosas con la Desestructuración de Arreglos y Objectos.</p><p>Gracias por leer. :)</p><p>Traducido del artículo de <strong><a href="https://www.freecodecamp.org/news/author/sarah/"><strong>Sarah Chima Atuonwu</strong></a><strong> - </strong><a href="https://www.freecodecamp.org/news/array-and-object-destructuring-in-javascript/">How to Use Array and Object Destructuring in JavaScript</a>.</strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Aprende Next.js desde Cero ]]>
                </title>
                <description>
                    <![CDATA[ Next.js [https://nextjs.org/] es un framework de JavaScript que nos permite crear fácilmente sitios web de React listos para salir a producción. En este artículo profundizaremos en la documentación oficial, desglosando los conceptos básicos, funciones y particularidades de Next.js. Cubriremos los siguientes temas:  * ¿Por qué usar Next.js?  * ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/aprende-next-js-desde-cero/</link>
                <guid isPermaLink="false">5fede0108c7cd154bb98225a</guid>
                
                    <category>
                        <![CDATA[ NextJS ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Wed, 20 Jan 2021 14:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/01/next-js-logo1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a href="https://nextjs.org/">Next.js</a> es un framework de JavaScript que nos permite crear fácilmente sitios web de React listos para salir a producción.</p><p>En este artículo profundizaremos en la documentación oficial, desglosando los conceptos básicos, funciones y particularidades de Next.js. Cubriremos los siguientes temas:</p><ul><li><a href="#-por-qu-usar-next-js">¿Por qué usar Next.js?</a></li><li><a href="#creando-nuestra-primera-aplicaci-n-con-next-js">Creando nuestra primera aplicación con Next.js</a></li><li><a href="#p-ginas-y-rutas">Páginas y Rutas</a></li><li><a href="#enlazando-p-ginas">Enlazando páginas</a></li><li><a href="#css-en-next-js">CSS en Next.js</a></li><li><a href="#recursos-est-ticos">Recursos estáticos</a></li><li><a href="#ssg-vs-ssr">SSG vs SSR</a></li><li><a href="#rutas-api">Rutas API</a></li><li><a href="#palabras-finales">Palabras finales</a></li></ul><h2 id="-por-qu-usar-next-js">¿Por qué usar Next.js?</h2><p>Next.js ofrece la mejor de las experiencias para el desarrollador, con múltiples funcionalidades incorporadas que garantizan la creación de proyectos sólidos listos para producción, estas son algunas de las razones para su uso:</p><ol><li>Facilidad para aprender y sin complejas configuraciones.</li><li>Optimizado para brindar mejoras de SEO y rendimiento.</li><li>Enrutamiento basado en páginas con soporte de rutas dinámicas.</li><li>Rutas API desplegadas en funciones Serverless.</li><li>Capacidad para generar sitios estáticos (SSG), usar server-side rendering (SSR) o una combinación de ambos según la necesidad de cada página.</li><li>Compatibilidad incorporada con CSS y SASS. Además de soporte para múltiples librerías de CSS en JS.</li></ol><h2 id="creando-nuestra-primera-aplicaci-n-con-next-js">Creando nuestra primera aplicación con Next.js</h2><h3 id="requisitos-previos">Requisitos Previos</h3><p>Antes que nada debes asegurarte de que tienes instalado <strong>Node.js </strong>en tu ordenador (v10.13 en adelante). Para ello, ejecutamos el siguiente comando desde el terminal:</p><pre><code class="language-bash">node -v</code></pre><p>Este comando te devolverá la versión de Node que tienes instalada actualmente.</p><h3 id="usando-create-next-app">Usando create-next-app</h3><p>La manera fácil y recomendada de crear nuevas aplicaciones de Next.JS es usando <code>create-next-app</code>, este se encargará de hacer todas las configuraciones básicas necesarias para empezar nuestro proyecto de inmediato. Ejecuta en tu terminal:</p><pre><code class="language-bash">npx create-next-app &lt;nombre-de-aplicacion&gt;</code></pre><p>Aquí <code>&lt;nombre-de-aplicacion&gt;</code> es el nombre que tendrá la carpeta que alojará los archivos de nuestro proyecto, por lo que puedes darle el nombre de tu preferencia.</p><p>Luego de que se complete la instalación, podemos iniciar el servidor de desarrollo ejecutando los siguientes comandos:</p><pre><code class="language-bash">cd &lt;nombre-de-aplicacion&gt;
npm run dev</code></pre><p>Si visitas <a href="http://localhost:3000/">localhost:3000</a> podrás ver en vivo tu nueva aplicación de Next.js.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2020/12/image-11.png" class="kg-image" alt="image-11" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2020/12/image-11.png 600w, https://www.freecodecamp.org/espanol/news/content/images/2020/12/image-11.png 968w" sizes="(min-width: 720px) 720px" width="968" height="744" loading="lazy"></figure><h3 id="manualmente">Manualmente</h3><p>También puedes utilizar Next.js instalando manualmente los paquetes: <code>next</code>, <code>react</code> y <code>react-dom</code>:</p><pre><code class="language-bash">npm install next react react-dom</code></pre><p>Luego abrimos el archivo <code>package.json</code> y añadimos los siguientes <code>scripts</code>: </p><pre><code class="language-json">"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start"
}</code></pre><ul><li><code>dev</code> inicia Next.js en modo desarrollo.</li><li><code>start</code> inicia Next.js en modo producción.</li><li><code>build</code> construye tu aplicación de Next.js para producción.</li></ul><h2 id="p-ginas-y-rutas">Páginas y Rutas</h2><p>Una de las particularidades de Next.js es que esta construido alrededor del concepto de páginas.</p><p>Una página es un componente de React exportado desde la carpeta <code>pages</code>.</p><p>Las páginas están asociadas con una ruta basada en el nombre del archivo. Por ejemplo <code>pages/perfil.js</code> resultará en la ruta <code>/perfil</code>. </p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">export default function Perfil() {
  return &lt;div&gt;¡Bienvenido a mi perfil!&lt;/div&gt;;
}</code></pre><figcaption>pages/perfil.js</figcaption></figure><p>Prueba el código anterior por tu cuenta y visita <a href="http://localhost:3000/perfil">localhost:3000/perfil</a> para ver los resultados.</p><h3 id="rutas-index">Rutas Index</h3><p>Los archivos con nombre <code>index</code> dirigen hacia la raíz del directorio que lo contiene.</p><ul><li><code>pages<em>/</em>index.js</code> → <code>/</code></li><li><code>pages/blog/index.js</code> → <code>/blog</code></li></ul><h3 id="rutas-anidadas">Rutas Anidadas</h3><p>Supongamos que queremos acceder a la siguiente ruta: <code>/blog/post/:id</code></p><p>Necesitaremos anidar las carpetas de la siguiente manera:</p><pre><code class="language-bash">|- pages
  |- index.js
  |- blog
    |- post
      |- [id].js # id dinámico para cada post</code></pre><h3 id="p-ginas-con-rutas-din-micas">Páginas con Rutas Dinámicas</h3><p>También podemos utilizar rutas dinámicas si agregamos corchetes al nombre del archivo. Por ejemplo, si creamos un archivo llamado <code>pages/post/[id].js</code> podremos acceder a el en las rutas <code>post/1</code>, <code>post/2</code>, y así sucesivamente.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import { useRouter } from "next/router";

export default function Post() {
  const router = useRouter();
  const { id } = router.query;

  return &lt;p&gt;Post: {id}&lt;/p&gt;;
}</code></pre><figcaption>pages/post/[id].js</figcaption></figure><p>Como puedes observar, en el código anterior utilizamos el hook <code>useRouter</code> de Next.js para acceder al objeto <code>router</code>, dicho objeto contiene propiedades muy útiles, las partes dinámicas de cada ruta se almacenan en <code>router.query</code>.</p><h2 id="enlazando-p-ginas">Enlazando páginas</h2><p>Para obtener una navegación fluida entre las páginas de nuestra aplicación, necesitamos importar el componente <code>Link</code> y usarlo de la siguiente manera:</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import Link from "next/link";

export default function Home() {
  return (
    &lt;ul&gt;
      &lt;li&gt;
        &lt;Link href="/"&gt;
          &lt;a&gt;Home&lt;/a&gt;
        &lt;/Link&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;Link href="/perfil"&gt;
          &lt;a&gt;Mi perfil&lt;/a&gt;
        &lt;/Link&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;Link href="/blog/post/hola-mundo"&gt;
          &lt;a&gt;Post&lt;/a&gt;
        &lt;/Link&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  );
}</code></pre><figcaption>pages/index.js</figcaption></figure><p>En el ejemplo anterior podemos observar que hay múltiples enlaces, cada uno cuenta con un componente <code>Link</code> que recibe una propiedad <code>href</code> indicando la ruta a la que dirige. <code>Link</code> envuelve un elemento Anchor <code>a</code> que contiene el texto de nuestro enlace.</p><h3 id="enlazando-rutas-din-micas">Enlazando Rutas Dinámicas</h3><p>También puedes utilizar interpolación para crear la ruta, lo que resulta útil para los segmentos de ruta dinámicos. Por ejemplo, para mostrar una lista de posts que se han pasado al componente como propiedad:</p><pre><code class="language-jsx">import Link from "next/link";

export default function Posts({ posts }) {
  return (
    &lt;ul&gt;
      {posts.map((post) =&gt; (
        &lt;li key={post.id}&gt;
          &lt;Link href={`/blog/post/${post.id}`}&gt;
            &lt;a&gt;{post.titulo}&lt;/a&gt;
          &lt;/Link&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  );
}</code></pre><p>O usando un objeto URL:</p><pre><code class="language-jsx">import Link from "next/link";

export default function Posts({ posts }) {
  return (
    &lt;ul&gt;
      {posts.map((post) =&gt; (
        &lt;li key={post.id}&gt;
          &lt;Link
            href={{
              pathname: "/blog/post/[id]",
              query: { id: post.id },
            }}
          &gt;
            &lt;a&gt;{post.titulo}&lt;/a&gt;
          &lt;/Link&gt;
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  );
}</code></pre><h2 id="css-en-next-js">CSS en Next.js</h2><p>Existen muchas formas de darle estilo a tu aplicación en Next.js, puedes importar archivos de hojas de estilo directamente gracias a la compatibilidad con los Módulos de CSS. Para ello el archivo debe nombrarse de la siguiente manera: <code>[nombre].module.css</code>.</p><p>Los Módulos de CSS mantienen un ámbito local creando clases únicas automáticamente, por lo que te permite usar los mismos nombres de clases en diferentes archivos sin que tengas que preocuparte por colisiones.</p><p>Por ejemplo, para crear un componente botón reusable, primero creamos <code>componentes/Boton.module.css</code> con el siguiente contenido:</p><figure class="kg-card kg-code-card"><pre><code class="language-css">.peligro {
  color: white;
  background-color: red;
}</code></pre><figcaption>componentes/Boton.module.css</figcaption></figure><p>Y un archivo <code>componentes/Boton.js</code> donde importar y usar el módulo CSS antes creado.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import estilos from "./Boton.module.css";

export default function Boton() {
  return (
    &lt;button type="button" className={estilos.peligro}&gt;
      Borrar
    &lt;/button&gt;
  );
}</code></pre><figcaption>componentes/Boton.js</figcaption></figure><blockquote>Nota: La clase <code>peligro</code> es una propiedad del objeto <code>estilos</code> importado.</blockquote><p>Así de fácil es usar los Módulos de CSS en Next.js, recuerda que también tenemos más opciones de estilo a nuestra disposición, tales como <a href="https://nextjs.org/docs/basic-features/built-in-css-support#sass-support">Sass</a>, <a href="https://nextjs.org/docs/basic-features/built-in-css-support#less-and-stylus-support">Less</a> o <a href="https://nextjs.org/docs/basic-features/built-in-css-support#css-in-js">CSS en JavaScript</a>. </p><h3 id="recursos-est-ticos">Recursos estáticos</h3><p>La carpeta <code>public</code> es utilizada en Next.js para servir todos nuestros recursos estáticos (imágenes, iconos, robots, entre otros). Puedes importar archivos dentro de la carpeta <code>public</code> &nbsp;usando (<code>/</code>) como URL base.</p><p>Por ejemplo, para acceder a una imagen guardada en <code>public/hero.jpg</code> escribimos un código como el siguiente:</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">export default function Home() {
  return (
    &lt;div&gt;
      &lt;img src="/hero.jpg" /&gt;
    &lt;/div&gt;
  );
}</code></pre><figcaption>pages/index.js</figcaption></figure><blockquote>Nota: No cambies el nombre de la carpeta <code>public</code> por ningún otro, es la única que puede servir recursos estáticos.</blockquote><h2 id="ssg-vs-ssr">SSG vs SSR</h2><h3 id="pre-renderizado">Pre-renderizado</h3><p>Next.js pre-renderiza cada página por defecto. Generando el HTML por adelantado en lugar de dejarle todo el trabajo al JavaScript del cliente. Esto se traduce en importantes mejoras de rendimiento y SEO.</p><p>Cada HTML generado se asocia con un mínimo de código de JavaScript requerido para esa página. Cuando una página es cargada por el navegador, su código JavaScript se ejecuta y hace la página plenamente interactiva. Este proceso es llamado hidratación.</p><h3 id="tipos-de-pre-renderizado">Tipos de Pre-renderizado</h3><p>Existen dos formas de pre-renderizado en Next.js:<strong> Static Site Generation</strong> y<strong> Server-side Rendering</strong>. La diferencia principal radica en <strong>cuando</strong> se genera el HTML para la página.</p><ul><li><strong>SSG</strong> (Static Site Generation): El HTML se genera <em>antes</em> de cada petición, como al momento de crear la build.</li><li><strong>SSR</strong> (Server-side Rendering): El HTML se genera en el servidor <em>durante</em> cada petición.</li></ul><h3 id="static-site-generation">Static Site Generation</h3><p>Si nuestra página no requiere datos de una fuente externa, Next.js se encargará de generarla de forma estática al crear la build. Por ejemplo:</p><pre><code class="language-jsx">export default function Perfil() {
  return &lt;div&gt;Perfil&lt;/div&gt;;
}</code></pre><p>En cambio, si el contenido o rutas de la página dependen de una fuente externa, necesitaremos usar dos funciones especiales de Next.js: <code>getStaticProps</code> y <code>getStaticPaths</code>.</p><p><strong>Ejemplo 1:</strong> Digamos que tu página necesita una lista de posts publicados en tu blog desde un CMS.</p><pre><code class="language-jsx">// TODO: Hacer fetch a los `posts` antes de que se pre-renderice la página
export default function Blog({ posts }) {
  return (
    &lt;ul&gt;
      {posts.map((post) =&gt; (
        &lt;li key={post.id}&gt;{post.titulo}&lt;/li&gt;
      ))}
    &lt;/ul&gt;
  );
}</code></pre><p>En el mismo archivo tenemos que exportar la función asíncrona <code>getStaticProps</code>, esta función es llamada al momento de crear la build y te permite pasar los datos recopilados a la página en forma de <code>props</code>.</p><pre><code class="language-jsx">export async function getStaticProps() {
  // Hacer fetch al endpoint que contiene los `posts`
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  return { props: { posts } };
}

export default function Blog({ posts }) {
  // Renderizar posts...
}</code></pre><p><strong>Ejemplo 2: </strong>Queremos pre-renderizar posts individuales usando rutas dinámicas.</p><p>Empezamos creando un archivo con ruta dinámica llamado <code>pages/posts/[id].js</code>, este nos permitirá acceder a nuestros posts según su <code>id</code>, con enlaces como: <code>/posts/1</code>, <code>/posts/2</code>, etc.</p><pre><code class="language-jsx">export default function Post({ post }) {
  return (
    &lt;div&gt;
      &lt;h1&gt;{post.titulo}&lt;/h1&gt;
      &lt;p&gt;{post.contenido}&lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre><p>Podemos indicar a Next.js las rutas dinámicas que queremos pre-renderizar usando la función <code>getStaticPaths</code>.</p><pre><code class="language-jsx">export async function getStaticPaths() {
  // Hacer fetch al endpoint que contiene los `posts`
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  // Obtener rutas a pre-renderizar basado en el `id` de los posts
  const rutas = posts.map((post) =&gt; `/posts/${post.id}`);

  return { paths: rutas, fallback: false };
}
</code></pre><blockquote>Nota: <code>{ fallback: false }</code> hace que las rutas no incluidas devuelvan una página 404.</blockquote><p>Finalmente, utilizamos <code>getStaticProps</code> para conseguir los datos del post según el <code>id</code> proporcionado en el objeto <code>params</code>.</p><pre><code class="language-jsx">export async function getStaticPaths() {
  // ...
}

export async function getStaticProps({ params }) {
  // params contiene el `id` del post.
  const res = await fetch(`https://.../posts/${params.id}`);
  const post = await res.json();

  // Pasar datos del post hacia la página en forma de props
  return { props: { post } };
}

export default function Post({ post }) {
  // Renderizar post...
}</code></pre><h3 id="server-side-rendering">Server-side Rendering</h3><p>Muchas veces los datos de nuestra página deben ser constantemente actualizados o tal vez necesitemos interactuar con una API haciendo consultas variadas y complejas. Para casos como estos, Next.js nos permite usar <strong>Server-side Rendering</strong> (SSR) en nuestras aplicaciones de React.</p><p>Cuando una página utiliza Server-side rendering, el HTML de la misma se genera en el servidor durante cada petición. Para ello, necesitamos exportar la función asíncrona <code>getServerSideProps</code>, la cual recopila los datos y los pasa a la página.</p><pre><code class="language-jsx">// Esta función es llamada durante cada petición
export async function getServerSideProps() {
  // Recopilar datos desde una API externa
  const res = await fetch(`https://.../datos`);
  const datos = await res.json();

  // Pasar datos hacia la pagina en forma de props
  return { props: { datos } };
}

export default function Pagina({ datos }) {
  // Renderizar datos...
}</code></pre><p>Como puedes observar, <code>getServerSideProps</code> y <code>getStaticProp</code> cuentan con una sintaxis y funcionamiento similar, pero se diferencian principalmente por el momento en que son ejecutadas.</p><h2 id="rutas-api">Rutas API</h2><p>Next.js provee una solución para construir APIs fácilmente en un entorno Serverless (Sin servidor), por lo que no tendremos que preocuparnos de pagar alojamiento de servidores para el back-end de nuestra aplicación.</p><p>Todos los archivos dentro de la carpeta <code>pages/api</code> serán tratados como endpoints de nuestra API en lugar de páginas. </p><p>Por ejemplo, si creamos un archivo <code>pages/api/hola.js</code> podremos acceder al mismo en la ruta: <code>/api/hola</code> y nos devolverá como respuesta un objeto json.</p><figure class="kg-card kg-code-card"><pre><code class="language-js">export default function manejador(req, res) {
  res.status(200).json({ texto: "Hola" });
}</code></pre><figcaption>pages/api/hola.js</figcaption></figure><p>Como puedes observar, para que este archivo funcione correctamente como API endpoint es necesario exportar una función manejador (handler) con los parámetros <code>req</code> y <code>res</code>.</p><p>Si queremos tener acceso a los diferentes métodos HTTP en nuestro manejador podemos usar <code>req.method</code> dentro del mismo, por ejemplo:</p><pre><code class="language-js">export default function manejador(req, res) {
  switch (req.method) {
    case "GET":
      // Nuestra lógica de código para el método GET...
      break;
    case "PATCH":
      // Nuestra lógica de código para el método PATCH...
      break;
    case "DELETE":
      // Nuestra lógica de código para el método DELETE...
      break;
    default:
      res.status(405).json({
        mensaje: `El método HTTP ${req.method} no esta disponible en esta ruta`,
      });
      break;
  }
}</code></pre><p>Si ya estás familiarizado con Express.js probablemente encuentres muchas similitudes en cuanto a sintaxis.</p><h2 id="palabras-finales">Palabras finales</h2><p>En este artículo pudimos explorar algunas de las funcionalidades principales de Next.js, mostrando una visión general de sus características, herramientas y ventajas tanto para el desarrollador como para el usuario final.</p><p>Espero que esta lectura haya sido de tu agrado y te animes a probar este framework por tu cuenta. Pienso más adelante crear contenido de Next.js tocando temas más específicos, tales como: middlewares, opciones de despliegues, enrutamiento internacionalizado (<strong>i18n</strong>), entres otros. </p><hr><p>¿Tienes alguna duda o quieres mantenerte al día con mis publicaciones? <a href="https://twitter.com/kelvin_sanchez">Sígueme en Twitter.</a></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Cómo construir una PWA desde cero con HTML, CSS y JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Las aplicaciones web progresivas son una forma de llevar esa sensación de aplicación nativa a una aplicación web tradicional. Con PWAs podemos mejorar nuestro sitio web con funcionalidades de aplicaciones móviles, aumentando la usabilidad y ofreciendo una excelente experiencia de usuario. En este artículo, vamos a crear una PWA desde ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/como-construir-una-pwa-desde-cero-con-html-css-y-javascript/</link>
                <guid isPermaLink="false">5fe894e48c7cd154bb97f744</guid>
                
                    <category>
                        <![CDATA[ PWA ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Tue, 19 Jan 2021 14:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2020/12/Group-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Las aplicaciones web progresivas son una forma de llevar esa sensación de aplicación nativa a una aplicación web tradicional. Con PWAs podemos mejorar nuestro sitio web con funcionalidades de aplicaciones móviles, aumentando la usabilidad y ofreciendo una excelente experiencia de usuario.</p><p>En este artículo, vamos a crear una PWA desde cero con HTML, CSS y JavaScript. Estos son los temas que cubriremos:</p><ul><li><a href="#-qu-es-una-aplicaci-n-web-progresiva">¿Qué es una aplicación web progresiva?</a></li><li><a href="#marcado-b-sico">Marcado básico</a></li><li><a href="#estilizando">Estilizando</a></li><li><a href="#mostrar-datos-con-javascript">Mostrar datos con JavaScript</a></li><li><a href="#manifiesto-de-aplicaci-n-web">Manifiesto de Aplicación Web</a></li><li>¿<a href="#-qu-es-un-service-worker">Qué es un Service Worker?</a></li><li><a href="#cach-de-recursos">Caché de recursos</a></li><li><a href="#fetch-de-recursos">Fetch de recursos</a></li><li><a href="#registrando-el-service-worker">Registrando el Service Worker</a></li><li><a href="#pensamientos-finales">Pensamientos finales</a></li><li><a href="#pr-ximos-pasos">Próximos pasos</a></li></ul><p>Entonces, comencemos con una pregunta importante: ¿Qué diablos es una PWA?</p><h2 id="-qu-es-una-aplicaci-n-web-progresiva"><strong>¿Qué es una aplicación web progresiva?</strong></h2><p>Una Aplicación Web Progresiva (PWA por sus siglas en inglés) es una aplicación web que ofrece a los usuarios una experiencia similar a la de aplicaciones nativas mediante el uso de capacidades web modernas. Al final, es solo un sitio web común que se ejecuta en el navegador con algunas mejoras. Dándote la habilidad de:</p><ul><li>Instalarla en una pantalla de inicio móvil</li><li>Acceder sin conexión</li><li>Acceder a la cámara</li><li>Recibir notificaciones push</li><li>Sincronizar en segundo plano</li></ul><p>Y mucho más.</p><p>Sin embargo, para poder transformar nuestra aplicación web tradicional en una PWA, tenemos que ajustarla un poco, agregando un archivo de manifiesto de aplicación web y un service worker.</p><p>No te preocupes por estos nuevos términos – los cubriremos más adelante.</p><p>Primero, tenemos que construir nuestra aplicación web tradicional. Así que comencemos con el marcado.</p><h2 id="marcado-b-sico"><strong>Marcado básico</strong></h2><p>El archivo HTML es relativamente simple. Envolvemos todo en la etiqueta <code>main</code>.</p><ul><li>En <code>index.html</code></li></ul><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="ie=edge" /&gt;
    &lt;link rel="stylesheet" href="css/style.css" /&gt;
    &lt;title&gt;Dev'Coffee PWA&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;main&gt;
      &lt;nav&gt;
        &lt;h1&gt;Dev'Coffee&lt;/h1&gt;
        &lt;ul&gt;
          &lt;li&gt;Home&lt;/li&gt;
          &lt;li&gt;About&lt;/li&gt;
          &lt;li&gt;Blog&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
      &lt;div class="container"&gt;&lt;/div&gt;
    &lt;/main&gt;
    &lt;script src="js/app.js"&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre><p>Se crea una barra de navegación con la etiqueta <code>nav</code>. Luego, el <code>div</code> con la clase <code>.container</code> guardará las tarjetas que agregaremos más tarde con JavaScript.</p><p>Una vez terminado el marcado básico, procedemos a darle estilo con CSS.</p><h2 id="estilizando"><strong>Estilizando</strong></h2><p>Aquí, como de costumbre, comenzamos importando las fuentes que necesitamos. Luego hacemos algunos restablecimientos para evitar el comportamiento predeterminado.</p><ul><li>En <code>css/style.css</code></li></ul><pre><code class="language-css">@import url("https://fonts.googleapis.com/css?family=Nunito:400,700&amp;display=swap");
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background: #fdfdfd;
  font-family: "Nunito", sans-serif;
  font-size: 1rem;
}
main {
  max-width: 900px;
  margin: auto;
  padding: 0.5rem;
  text-align: center;
}
nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
ul {
  list-style: none;
  display: flex;
}

li {
  margin-right: 1rem;
}
h1 {
  color: #e74c3c;
  margin-bottom: 0.5rem;
}
</code></pre><p>Ahora, limitamos el ancho máximo del elemento <code>main</code> a <code>900px</code> para que se vea bien en una pantalla grande.</p><p>Para la barra de navegación, quiero que el logo esté a la izquierda y los enlaces a la derecha. Por lo que en la etiqueta <code>nav</code>, después de convertirla en un contenedor flexible, usamos <code>justify-content: space-between;</code> para alinearlos.</p><ul><li>En <code>css/style.css</code></li></ul><pre><code class="language-css">.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  grid-gap: 1rem;
  justify-content: center;
  align-items: center;
  margin: auto;
  padding: 1rem 0;
}
.card {
  display: flex;
  align-items: center;
  flex-direction: column;
  width: 15rem auto;
  height: 15rem;
  background: #fff;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
  border-radius: 10px;
  margin: auto;
  overflow: hidden;
}
.card--avatar {
  width: 100%;
  height: 10rem;
  object-fit: cover;
}
.card--title {
  color: #222;
  font-weight: 700;
  text-transform: capitalize;
  font-size: 1.1rem;
  margin-top: 0.5rem;
}
.card--link {
  text-decoration: none;
  background: #db4938;
  color: #fff;
  padding: 0.3rem 1rem;
  border-radius: 20px;
}
</code></pre><p>Tendremos varias tarjetas, por lo que el elemento container se mostrará como una cuadrícula. Con <code>grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr))</code> podemos hacer que nuestras tarjetas sean responsivas, usando al menos <code>15rem</code> de ancho si hay suficiente espacio (y <code>1fr</code> si no).</p><p>Finalmente, para que estas luzcan mejor, duplicamos el efecto de sombra en la clase <code>.card</code> y usamos <code>object-fit: cover</code> en <code>.card--avatar</code> para evitar que la imagen se estire.</p><p>Con esto, nuestra aplicación web se ve mucho mejor – pero todavía no tenemos datos para mostrar.</p><p>Arreglemoslo en la siguiente sección.</p><h2 id="mostrar-datos-con-javascript"><strong>Mostrar datos con JavaScript</strong></h2><blockquote>Puedes descargar todos los recursos que usé para la creación de esta aplicación web <a href="https://github.com/ibrahima92/pwa-with-vanilla-js/archive/master.zip">aquí</a>.</blockquote><p>Observa que utilicé imágenes grandes que tardan algún tiempo en cargarse. Esto te mostrará de la mejor manera el poder de los service workers.</p><p>Como dije antes, la clase <code>.container</code> tendrá nuestras tarjetas. Por lo tanto, debemos seleccionarlo.</p><ul><li>En <code>js/app.js</code></li></ul><pre><code class="language-javascript">const container = document.querySelector(".container")
const coffees = [
  { name: "Perspiciatis", image: "images/coffee1.jpg" },
  { name: "Voluptatem", image: "images/coffee2.jpg" },
  { name: "Explicabo", image: "images/coffee3.jpg" },
  { name: "Rchitecto", image: "images/coffee4.jpg" },
  { name: " Beatae", image: "images/coffee5.jpg" },
  { name: " Vitae", image: "images/coffee6.jpg" },
  { name: "Inventore", image: "images/coffee7.jpg" },
  { name: "Veritatis", image: "images/coffee8.jpg" },
  { name: "Accusantium", image: "images/coffee9.jpg" },
]
</code></pre><p>Luego, creamos un arreglo de tarjetas con nombres e imágenes.</p><ul><li>En <code>js/app.js</code></li></ul><pre><code class="language-javascript">const showCoffees = () =&gt; {
  let output = ""
  coffees.forEach(
    ({ name, image }) =&gt;
      (output += `
              &lt;div class="card"&gt;
                &lt;img class="card--avatar" src=${image} /&gt;
                &lt;h1 class="card--title"&gt;${name}&lt;/h1&gt;
                &lt;a class="card--link" href="#"&gt;Taste&lt;/a&gt;
              &lt;/div&gt;
              `)
  )
  container.innerHTML = output
}

document.addEventListener("DOMContentLoaded", showCoffees)
</code></pre><p>El código anterior nos permite recorrer el arreglo y mostrar su contenido en el archivo HTML. Y para que todo funcione, esperamos hasta que el contenido del DOM (del inglés Document Object Model) termine de cargarse y así ejecutar el método <code>showCoffees</code>.</p><p>Hemos hecho mucho, pero por ahora solo tenemos una aplicación web tradicional. Así que cambiemos eso en la siguiente sección, presentando algunas funcionalidades de las PWAs.</p><figure class="kg-card kg-image-card"><img src="https://media.giphy.com/media/l3V0dy1zzyjbYTQQM/source.gif" class="kg-image" alt="super-excited" width="500" height="281" loading="lazy"></figure><h2 id="manifiesto-de-aplicaci-n-web"><strong>Manifiesto de Aplicación Web</strong></h2><p>El manifiesto de aplicación web es un archivo JSON simple que informa al navegador sobre tu aplicación web. Indica cómo debe comportarse cuando se instala en el dispositivo móvil o escritorio del usuario. Si queremos que se muestre el mensaje <em>Agregar a la Pantalla de Inicio</em>, requeriremos el manifiesto de aplicación web.</p><p>Ahora que sabemos qué es un manifiesto web, creemos un nuevo archivo llamado <code>manifest.json</code> (tienes que nombrarlo así) en el directorio raíz. Luego agrega el siguiente bloque de código.</p><ul><li>En <code>manifest.json</code></li></ul><pre><code class="language-javascript">{
  "name": "Dev'Coffee",
  "short_name": "DevCoffee",
  "start_url": "index.html",
  "display": "standalone",
  "background_color": "#fdfdfd",
  "theme_color": "#db4938",
  "orientation": "portrait-primary",
  "icons": [
    {
      "src": "/images/icons/icon-72x72.png",
      "type": "image/png", "sizes": "72x72"
    },
    {
      "src": "/images/icons/icon-96x96.png",
      "type": "image/png", "sizes": "96x96"
    },
    {
      "src": "/images/icons/icon-128x128.png",
      "type": "image/png","sizes": "128x128"
    },
    {
      "src": "/images/icons/icon-144x144.png",
      "type": "image/png", "sizes": "144x144"
    },
    {
      "src": "/images/icons/icon-152x152.png",
      "type": "image/png", "sizes": "152x152"
    },
    {
      "src": "/images/icons/icon-192x192.png",
      "type": "image/png", "sizes": "192x192"
    },
    {
      "src": "/images/icons/icon-384x384.png",
      "type": "image/png", "sizes": "384x384"
    },
    {
      "src": "/images/icons/icon-512x512.png",
      "type": "image/png", "sizes": "512x512"
    }
  ]
}
</code></pre><p>Al final, es solo un archivo JSON con algunas propiedades obligatorias y otras opcionales.</p><p><code>name</code> (nombre): Cuando el navegador inicie la pantalla de bienvenida, será el nombre que se muestre en la pantalla.</p><p><code>short_name</code> (nombre corto): Será el nombre que se muestre debajo del acceso directo de la aplicación en la pantalla de inicio.</p><p><code>start_url</code> (url de inicio): Será la página que se muestre al usuario una vez abierta tu aplicación.</p><p><code>display</code>: Le dice al navegador cómo mostrar la aplicación. Hay varios modos como <code>minimal-ui</code>, <code>fullscreen</code>, <code>browser</code>, etc. Aquí, utilizamos el modo <code>standalone</code> para ocultar todo lo relacionado con el navegador.</p><p><code>background_color</code> (color de fondo): Cuando el navegador inicie la pantalla de bienvenida, será el fondo pantalla.</p><p><code>theme_colo</code>r (color de tema): Será el color de fondo de la barra de estado cuando abramos la aplicación.</p><p><code>orientation</code> (orientación): Le dice al navegador la orientación que debe tener al mostrar la aplicación.</p><p><code>icons</code> (iconos): Cuando el navegador inicie la pantalla de bienvenida, será el icono que se muestre en la pantalla. Aquí utilicé todos los tamaños para tener compatibilidad con el icono preferido de cualquier dispositivo. Pero puedes usar uno o dos. Tú decides.</p><p>Ahora que tenemos un manifiesto de aplicación web, lo agregamos al archivo HTML.</p><ul><li>En <code>index.html</code> (etiqueta head)</li></ul><pre><code class="language-html">&lt;link rel="manifest" href="manifest.json" /&gt;
&lt;!-- Soporte para iOS --&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-72x72.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-96x96.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-128x128.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-144x144.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-152x152.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-192x192.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-384x384.png" /&gt;
&lt;link rel="apple-touch-icon" href="images/icons/icon-512x512.png" /&gt;
&lt;meta name="apple-mobile-web-app-status-bar" content="#db4938" /&gt;
&lt;meta name="theme-color" content="#db4938" /&gt;
</code></pre><p>Como puedes ver, vinculamos nuestro archivo <code>manifest.json</code> a la etiqueta head. Y agregamos algunos otros enlaces que manejan el soporte de iOS para mostrar los íconos y colorear la barra de estado con nuestro color de tema.</p><p>Ahora podemos pasar a la parte final e introducir el service worker.</p><h2 id="-qu-es-un-service-worker"><strong>¿Qué es un Service Worker?</strong></h2><p>Ten en cuenta que las PWA se ejecutan solo en https porque el service workers puede acceder a la solicitud y manejarla. Por lo tanto, se requiere seguridad.</p><p>Un service worker es un script que tu navegador ejecuta en segundo plano en un hilo separado. Eso significa que se ejecuta en un lugar diferente y está completamente separado de tu página web. Esa es la razón por la que no puede manipular elementos en el DOM.</p><p>Sin embargo, es superpoderoso. El service worker puede interceptar y manejar solicitudes de red, administrar el caché para habilitar el soporte fuera de línea o enviar notificaciones push a tus usuarios.</p><figure class="kg-card kg-image-card"><img src="https://media.giphy.com/media/5VKbvrjxpVJCM/source.gif" class="kg-image" alt="wow" width="470" height="376" loading="lazy"></figure><p>Entonces, creemos nuestro primer service worker en la carpeta raíz nombrándolo <code>serviceWorker.js</code> (el nombre depende de ti). Pero tienes que ponerlo en la raíz para no limitar su alcance a una sola carpeta.</p><h3 id="cach-de-recursos"><strong>Caché de recursos</strong></h3><ul><li>En <code>serviceWorker.js</code></li></ul><pre><code class="language-javascript">const staticDevCoffee = "dev-coffee-site-v1"
const assets = [
  "/",
  "/index.html",
  "/css/style.css",
  "/js/app.js",
  "/images/coffee1.jpg",
  "/images/coffee2.jpg",
  "/images/coffee3.jpg",
  "/images/coffee4.jpg",
  "/images/coffee5.jpg",
  "/images/coffee6.jpg",
  "/images/coffee7.jpg",
  "/images/coffee8.jpg",
  "/images/coffee9.jpg",
]

self.addEventListener("install", installEvent =&gt; {
  installEvent.waitUntil(
    caches.open(staticDevCoffee).then(cache =&gt; {
      cache.addAll(assets)
    })
  )
})
</code></pre><p>Este código parece intimidante al principio, pero es solo JavaScript (así que no te preocupes).</p><p>Declaramos el nombre de nuestro caché <code>staticDevCoffee</code> y los recursos (assets) para almacenar en el mismo. Para realizar esta acción, necesitamos adjuntar un event listener a <code>self</code>.</p><p><code>self</code> es el propio service worker. Nos permite escuchar los eventos del ciclo de vida y hacer algo a cambio.</p><p>El service worker tiene varios ciclos de vida y uno de ellos es el evento <code>install</code>. Se ejecuta cuando se instala el service worker. Se activa tan pronto se ejecuta y solo es llamado una vez por cada service worker.</p><p>Cuando se dispara el evento <code>install</code>, ejecutamos el callback que nos da acceso al objecto <code>event</code>. </p><p>Almacenar cosas en la caché del navegador puede tardar un tiempo en finalizar porque es asíncrono.</p><p>Entonces, para manejarlo necesitamos usar el método <code>waitUntil()</code>, el cual espera a que termine la acción.</p><p>Una vez que la API de caché este lista, podemos ejecutar el método <code>open()</code> y crear nuestra caché pasando su nombre como argumento a <code>caches.open(staticDevCoffee)</code>.</p><p>Luego esta devuelve una promesa, que nos ayuda a almacenar nuestros recursos en la caché con <code>cache.addAll(assets)</code>.</p><figure class="kg-card kg-image-card"><img src="https://drive.google.com/uc?id=1ynBQRQ00wHo5J6CnjfLCX3b3UNiSrGqZ" class="kg-image" alt="image-cache" width="600" height="400" loading="lazy"></figure><p>Con suerte, todavía estás conmigo.</p><figure class="kg-card kg-image-card"><img src="https://media.giphy.com/media/OQEcw90jACeU8/source.gif" class="kg-image" alt="desesperate" width="150" height="123" loading="lazy"></figure><p>Ahora, hemos almacenado con éxito nuestros recursos en el caché del navegador. Y la próxima vez que carguemos la página, el service worker manejará la solicitud y buscará el caché si estamos fuera de línea.</p><p>Por lo que toca recuperar nuestro caché.</p><h3 id="fetch-de-recursos"><strong>Fetch de recursos</strong></h3><ul><li>En <code>serviceWorker.js</code></li></ul><pre><code class="language-javascript">self.addEventListener("fetch", fetchEvent =&gt; {
  fetchEvent.respondWith(
    caches.match(fetchEvent.request).then(res =&gt; {
      return res || fetch(fetchEvent.request)
    })
  )
})
</code></pre><p>Aquí usamos el evento <code>fetch</code> para recuperar nuestros datos. El callback nos da acceso a <code>fetchEvent</code>. Luego le adjuntamos <code>respondWith()</code> para evitar la respuesta predeterminada del navegador. En su lugar devuelve una promesa, ya que la acción de recuperación puede tardar un tiempo en completarse.</p><p>Y una vez listo el caché, aplicamos el método <code>caches.match(fetchEvent.request)</code>. Este verificará si algo en el caché coincide con <code>fetchEvent.request</code>. Por cierto, <code>fetchEvent.request</code> es solo nuestro arreglo de recursos.</p><p>Luego, este devuelve una promesa. Y finalmente, podemos devolver el resultado si existe o el fetch inicial si no.</p><p>Ahora, nuestros recursos pueden ser almacenados en caché y recuperados por el service worker, lo que aumenta bastante el tiempo de carga de nuestras imágenes.</p><p>Y lo más importante, hace que nuestra aplicación esté disponible en modo fuera de línea.</p><p>Pero un service worker por si solo no puede hacer el trabajo. Necesitamos registrarlo en nuestro proyecto.</p><figure class="kg-card kg-image-card"><img src="https://media.giphy.com/media/Z9EvIRmLEOS3JNFeVb/source.gif" class="kg-image" alt="let-s-do-it" width="320" height="180" loading="lazy"></figure><h2 id="registrando-el-service-worker"><strong>Registrando el Service Worker</strong></h2><ul><li>En <code>js/app.js</code></li></ul><pre><code class="language-javascript">if ("serviceWorker" in navigator) {
  window.addEventListener("load", function() {
    navigator.serviceWorker
      .register("/serviceWorker.js")
      .then(res =&gt; console.log("service worker registered"))
      .catch(err =&gt; console.log("service worker not registered", err))
  })
}
</code></pre><p>Aquí, comenzamos verificando si <code>serviceWorker</code> es compatible con el navegador actual (ya que todavía no es compatible con todos los navegadores).</p><p>Luego, escuchamos el evento de carga de la página para registrar nuestro service worker pasando el nombre de nuestro archivo <code>serviceWorker.js</code> a <code>navigator.serviceWorker.register()</code> como parámetro para registrar nuestro worker.</p><p>Con esta actualización, ahora hemos transformado nuestra aplicación web habitual en una PWA.</p><figure class="kg-card kg-image-card"><img src="https://media.giphy.com/media/3o6ZtlGkjeschymLNm/source.gif" class="kg-image" alt="we-did-it" width="480" height="266" loading="lazy"></figure><h2 id="pensamientos-finales"><strong>Pensamientos finales</strong></h2><p>A lo largo de este artículo, hemos visto lo increíbles que pueden ser las PWAs. Al agregar un archivo de manifiesto de aplicación web y un service worker, se obtiene una mejora importante de la experiencia de usuario en nuestra aplicación web tradicional. Esto se debe a que las PWAs son rápidas, seguras, confiables y – &nbsp;lo más importante – &nbsp;habilitan el modo fuera de línea.</p><p>Muchos frameworks ahora vienen con un archivo de service worker ya configurado para nosotros. Pero saber cómo implementarlo puramente con JavaScript puede ayudarte a comprender mejor las PWAs.</p><p>Y puedes ir aún más lejos con los service workers, almacenando en caché los recursos de forma dinámica, limitando el tamaño de dicha caché, y mucho más.</p><p>Gracias por leer este artículo.</p><p>Puedes ver un demo de lo que creamos <a href="https://devcoffee-pwa.netlify.com/">aquí</a> y el código fuente <a href="https://github.com/ibrahima92/pwa-with-vanilla-js">acá</a>.</p><p>Lee más de mis artículos en <a href="https://www.ibrahima-ndaw.com/blog/how-to-build-pwa-with-javascript/">mi blog</a>.</p><p>Traducido del artículo de <strong><a href="https://www.freecodecamp.org/news/author/ibrahima92/"><strong>Ibrahima Ndaw</strong></a><strong> - </strong><a href="https://www.freecodecamp.org/news/build-a-pwa-from-scratch-with-html-css-and-javascript/">How to build a PWA from scratch with HTML, CSS, and JavaScript</a></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Ordenar Arreglos en JavaScript - Cómo usar el método sort() (Con ejemplos de código) ]]>
                </title>
                <description>
                    <![CDATA[ En JavaScript, podemos ordenar los elementos de un arreglo fácilmente con el método incorporado sort(). Sin embargo, los tipos de datos (cadena, número, etc.) pueden diferir de un arreglo a otro. Esto significa que usar únicamente el método sort() no siempre es la solución adecuada. En este post, aprenderás como ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/ordenar-arreglos-en-javascript-como-usar-el-metodo-sort/</link>
                <guid isPermaLink="false">5fe612cc8c7cd154bb97e1a6</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Thu, 14 Jan 2021 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/04/photo-1522252234503-e356532cafd5.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>En JavaScript, podemos ordenar los elementos de un arreglo fácilmente con el método incorporado <code>sort()</code>.</p><p>Sin embargo, los tipos de datos (cadena, número, etc.) pueden diferir de un arreglo a otro. Esto significa que usar únicamente el método <code>sort()</code> no siempre es la solución adecuada.</p><p>En este post, aprenderás como ordenar un arreglo en JavaScript usando el método <code>sort()</code> con cadenas y números.</p><h2 id="arreglo-de-cadenas"><strong>Arreglo de Cadenas</strong></h2><p>Comencemos con cadenas:</p><pre><code class="language-javascript">const equipos = ['Real Madrid', 'Manchester Utd', 'Bayern Munich', 'Juventus'];</code></pre><p>Cuando usamos el método <code>sort()</code>, los elementos se ordenarán en orden ascendente (de la A a la Z) por defecto:</p><pre><code class="language-javascript">equipos.sort(); 

// ['Bayern Munich', 'Juventus', 'Manchester Utd', 'Real Madrid']</code></pre><p>Si prefieres ordenar el arreglo en orden descendente, debes usar el método <code>reverse()</code> en su lugar:</p><pre><code class="language-javascript">equipos.reverse();

// ['Real Madrid', 'Manchester Utd', 'Juventus', 'Bayern Munich']</code></pre><h2 id="arreglo-de-n-meros">Arreglo de Números</h2><p>Lamentablemente, ordenar números no es tan simple. Si aplicamos el método <code>sort()</code> directamente a un arreglo de números, veremos un resultado inesperado:</p><pre><code class="language-javascript">const numeros = [3, 23, 12];

numeros.sort(); // --&gt; 12, 23, 3</code></pre><h3 id="por-qu-el-m-todo-sort-no-funciona-con-n-meros"><strong>Por qué el método sort() no funciona con números</strong></h3><p>En realidad está funcionando, pero este problema ocurre porque JavaScript ordena los números alfabéticamente. Déjame explicarte esto en detalle.</p><p>Pensemos en A=1, B=2 y C=3.</p><pre><code class="language-javascript">const miArreglo = ['C', 'BC', 'AB'];

miArreglo.sort(); // [AB, BC, C]</code></pre><p>Por ejemplo, si tenemos tres cadenas como C (3), BC (23) y AB (12), JavaScript las ordenará como AB, BC y C en orden ascendente, lo que es alfabéticamente correcto.</p><p>Sin embargo, JavaScript ordenará los números (alfabéticamente nuevamente) como 12, 23 y 3, lo cual es incorrecto.</p><h3 id="soluci-n-la-funci-n-de-comparaci-n"><strong>Solución: la función de comparación</strong></h3><p>Afortunadamente, podemos complementar el método <code>sort()</code> con una función de comparación básica que haga el truco:</p><pre><code class="language-javascript">function(a, b) {return a - b}</code></pre><p>El método <code>sort()</code> puede ordenar valores negativos, cero y positivos en el orden correcto. Cuando compara dos valores, los envía a nuestra función de comparación y luego ordena los valores de acuerdo al resultado devuelto.</p><ul><li>Si el resultado es negativo, <strong>a</strong> se ordena antes que <strong>b</strong>.</li><li>Si el resultado es positivo, <strong>b</strong> se ordena antes de <strong>a</strong>.</li><li>Si el resultado es 0, nada cambia.</li></ul><p>Todo lo que necesitamos es usar la función de comparación dentro del método <code>sort()</code>:</p><pre><code class="language-javascript">const numeros = [3, 23, 12];

numeros.sort(function(a, b){return a - b}); // --&gt; 3, 12, 23</code></pre><p>Si queremos ordenar los números en orden descendente, esta vez necesitamos restar el segundo parámetro (b) del primero (a):</p><pre><code class="language-javascript">const numeros = [3, 23, 12];

numeros.sort(function(a, b){return b - a}); // --&gt; 23, 12, 3</code></pre><h2 id="en-conclusi-n">En conclusión</h2><p>Como podemos ver, ordenar los elementos de un arreglo puede hacerse fácilmente en JavaScript con el método <code>sort()</code>, si sabemos usarlo correctamente. Espero que mi post pueda servirte de ayuda para entenderlo y usarlo de la mejor forma.</p><p><strong><strong>Si desea</strong>s<strong> obtener más información sobre </strong>D<strong>esarrollo </strong>W<strong>eb, no dude</strong>s<strong> en visitar mi <a href="https://www.youtube.com/channel/UC1EgYPCvKCXFn8HlpoJwY3Q?view_as=subscriber">canal de Youtube</a> .</strong></strong></p><p>¡Gracias por leer!</p><p>Traducido del artículo de <strong><a href="https://www.freecodecamp.org/news/author/cemeygi/"><strong>Cem Eygi</strong></a><strong> - </strong><a href="https://www.freecodecamp.org/news/javascript-array-sort-tutorial-how-to-use-js-sort-methods-with-code-examples/">JavaScript Array Sort – How to Use JS Sort Methods (With Code Examples)</a></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Una guía rápida para cambiar tu nombre de usuario en GitHub ]]>
                </title>
                <description>
                    <![CDATA[ Algunos pasos adicionales a considerar después de realizar un cambio en tu nombre de usuario en GitHub. Siendo esta la 238,947,234 vez y probablemente última vez que cambiaré mi nombre de usuario (el matrimonio es permanente, ¿verdad?), pensé que sería mejor escribir un post rápido sobre cómo se puede lograr ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/una-guia-rapida-para-cambiar-tu-nombre-de-usuario-en-github/</link>
                <guid isPermaLink="false">5fe208bf8c7cd154bb97c91d</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Wed, 06 Jan 2021 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2020/12/barcat.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="algunos-pasos-adicionales-a-considerar-despu-s-de-realizar-un-cambio-en-tu-nombre-de-usuario-en-github-"><strong>Algunos pasos adicionales a considerar después de realizar un cambio en tu nombre de usuario en GitHub.</strong></h2><p>Siendo esta la 238,947,234 vez y probablemente última vez que cambiaré mi nombre de usuario (el matrimonio es permanente, ¿verdad?), pensé que sería mejor escribir un post rápido sobre cómo se puede lograr esta transición de la manera más fluida posible. La siguiente es una guía rápida de algunas cosas a considerar <em><em><em><em>después.</em></em></em></em></p><h1 id="donde-hacer-cambios"><strong>Donde hacer cambios</strong></h1><ol><li>Cambia tu nombre de usuario haciendo clic en <strong>Change username</strong> en las <a href="https://github.com/settings/admin">opciones de tu cuenta de GitHub</a>.</li><li>Si usas GitHub Pages, cambia el nombre de tu repositorio “nombredeusuario.github.io”.</li><li>Si usas otros servicios que apunten a tu dirección de repositorio "nombredeusuario.github.io", actualízalos.</li><li>Si usas Netlify, es <em><em><em><em>posible que</em></em></em></em> desees iniciar sesión y volver a conectar tus repositorios.</li><li>Inicia sesión en Travis CI y otras integraciones, encuéntralas en la pestaña (Settings -&gt; Integrations) de tu repositorio. Esto actualizará tu nombre de usuario allí.</li><li>Actualiza tus archivos locales y enlaces de repositorio usando muy cuidadosamente comandos <code>find</code> y <code>sed</code>, empujando luego los cambios a GitHub.</li><li>Relanza cualquier sitio web que puedas tener con tu enlace de GitHub actualizado.</li><li>Corrige cualquier enlace en la web hacia tu perfil, tus repositorios, o Gists que hayas compartido.</li></ol><h1 id="actualizaci-n-de-archivos-locales"><strong>Actualización de archivos locales</strong></h1><p>Aquí hay algunas sugerencias de cadenas para buscar y reemplazar tu nombre de usuario.</p><ul><li><code>github.com/nombredeusuario</code> (Referencias a tu página de GitHub en READMEs o en la copia del sitio web)</li><li><code>nombredeusuario.github.io</code> (Enlaces a tu página de GitHub)</li><li><code>git@github.nombredeusuario</code> (URL ssh remotas de configuración de Git)</li><li><code>travis-ci.com/nombredeusuario</code>(Insignias de Travis en READMEs)</li><li><code>shields.io/github/.../nombredeusuario</code>(Insignias Shields en READMEs, incluyen <code>contribuyentes</code>, <code>estrellas</code>, <code>etiquetas</code>, y más)</li></ul><p>Puedes identificar rápidamente dónde se encuentran las cadenas anteriores utilizando este comando para cada cadena:</p><p><code>grep -rnw -e 'foobar'</code></p><p>Esto buscará recursivamente (<code>r</code>) todos los archivos para cadenas que coincidan con todo (<code>w</code>) el patrón (<code>e</code>) proporcionado y antepondrá los resultados con los números de línea (<code>n</code>) para que puedas encontrarlos fácilmente.</p><p>Usando <code>find</code> y <code>sed</code> puedes hacer estos cambios mucho más rápido. Consulta <a href="https://victoria.dev/verbose/how-to-replace-a-string-in-a-dozen-old-blog-posts-with-one-sed-terminal-command/?source=post_page---------------------------">este artículo sobre buscar y reemplazar</a> .</p><p>¡Disfruta tu nuevo nombre! (Espero que este haga click contigo.)</p><p>Traducido del artículo de <strong><strong><a href="https://www.freecodecamp.org/news/author/victoria/">Victoria Drake</a></strong> <strong>- </strong><a href="https://www.freecodecamp.org/news/a-quick-guide-to-changing-your-github-username/">A quick guide to changing your GitHub username</a></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Subir a GitHub - lo suficientemente simple para Poetas ]]>
                </title>
                <description>
                    <![CDATA[ Cuando comencé a empujar contenido de forma activa a Github, no hice contribuciones de Código Abierto, Componentes ni nada por el estilo - Empujé poesía. Hice esto, porque es lo que más amo después de la programación. Estaré agradecido siempre por haber tomado la iniciativa de hacer mi primer git ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/subir-a-github-lo-suficientemente-simple-para-poetas/</link>
                <guid isPermaLink="false">5fe1e01a8c7cd154bb97c75a</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Tue, 05 Jan 2021 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/04/photo-1561164517-686f490ee86d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Cuando comencé a empujar contenido de forma activa a Github, no hice contribuciones de Código Abierto, Componentes ni nada por el estilo - Empujé poesía. Hice esto, porque es lo que más amo después de la programación. Estaré agradecido siempre por haber tomado la iniciativa de hacer mi primer <code>git commit</code>.</p><p>Ahora, quiero desglosar el proceso para los nuevos programadores (y poetas - con suerte), para que también se sientan cómodos trabajando con Github. Explicaré diferentes formas de empujar contenido a esta plataforma. </p><p>Para los efectos de este artículo, asumiré que los lectores están familiarizados con el uso de la terminal (GitBash o de otro tipo).</p><hr><h3 id="empujar-a-un-nuevo-repositorio-con-un-archivo-readme-l-eme-">Empujar a un nuevo repositorio con un archivo README (Léeme)</h3><p>Solo hay algunos pasos esenciales para hacer esto:</p><ul><li>Has clic en el botón verde Code (Código) en la página del repositorio.</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2020/12/green-code-button.png" class="kg-image" alt="green-code-button" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2020/12/green-code-button.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2020/12/green-code-button.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2020/12/green-code-button.png 1148w" sizes="(min-width: 720px) 720px" width="1148" height="141" loading="lazy"></figure><ul><li>Usa la opción Clone -&gt; HTTPS, y copia el enlace proporcionado.</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2020/12/copy-https-url2.png" class="kg-image" alt="copy-https-url2" width="423" height="358" loading="lazy"></figure><ul><li>Ejecuta <code>git clone https://github.com/nombreDeUsuario/repositorio.git</code> en la terminal. Aquí, <strong><em>nombrelDeUsuario</em></strong> y <strong><em>repositorio </em></strong>serán reemplazados por los valores proporcionados en el enlace copiado.</li><li>Ejecuta <code>git init</code> en la terminal. Esto inicializará la carpeta/repositorio que tienes en tu computador local.</li><li>Ejecuta <code>git add .</code> en la terminal. Esto hará un seguimiento de los cambios realizados en la carpeta de tu sistema desde el último commit. Si es la primera vez que haces commit a los contenidos de la carpeta, se añadirán todos.</li><li>Ejecuta <code>git commit -m "inserta Mensaje aquí"</code>. Esto preparará los cambios añadidos/rastreados en la carpeta de tu sistema para empujar a Github. Puedes reemplazar <strong><em>inserta el Mensaje aquí</em></strong> con cualquier mensaje de confirmación relevante de tu elección.</li><li>Finalmente, ejecuta <code>git push origin master</code> para empujar tus archivos a Github. Ten en cuenta que la última palabra<strong><em> </em></strong>en el comando <strong><strong><em><em>m</em></em></strong><em>aster</em></strong>, no es una entrada fija cuando se ejecuta <code>git push</code>, puede ser reemplazada por cualquier “nombre_de_rama” relevante.</li></ul><hr><h3 id="como-empujar-c-digo-existente-a-un-nuevo-repositorio-de-github"><strong>Como empujar Código Existente a un nuevo repositorio de Github</strong></h3><blockquote><em><em>"</em>Programar<em> es algo hermoso. ¡Cualquiera puede aprender a </em>programar<em>!"</em></em></blockquote><p>Necesitas seguir los siguiente pasos:</p><ul><li>Copia el enlace <code>HTTPS</code> proporcionado al momento de crear el nuevo repositorio.</li></ul><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/espanol/news/content/images/2020/12/ejemplo.png" class="kg-image" alt="Example Empty Repo" srcset="https://www.freecodecamp.org/espanol/news/content/images/size/w600/2020/12/ejemplo.png 600w, https://www.freecodecamp.org/espanol/news/content/images/size/w1000/2020/12/ejemplo.png 1000w, https://www.freecodecamp.org/espanol/news/content/images/2020/12/ejemplo.png 1153w" sizes="(min-width: 720px) 720px" width="1153" height="459" loading="lazy"></figure><ul><li>Ejecuta <code>git init</code> en la terminal. Esto inicializará la carpeta/repositorio que tienes en tu computador local.</li><li>Ejecuta <code>git add .</code> en la terminal. Esto hará un seguimiento de los cambios realizados en la carpeta de tu sistema desde el último commit. Como es esta la primera vez que haces commit a los contenidos de la carpeta, se añadirán todos.</li><li>Ejecuta <code>git commit -m "inserta Mensaje aquí"</code>. Esto preparará los cambios añadidos/rastreados en la carpeta de tu sistema para empujar a Github. Puedes reemplazar <strong><em>inserta el Mensaje aquí</em></strong> con cualquier mensaje de confirmación relevante de tu elección.</li><li>Ejecuta <code>git remote add origin https://github.com/nombreDeUsuario/repositorio.git</code> en la terminal. Aquí, <strong><em>nombreDeUsuario</em></strong> y <strong><em>repositorio</em></strong> serán reemplazados por los valores proporcionados en el enlace copiado. Esto conectará la carpeta existente en tu sistema local al repositorio de Github <strong><strong>recién creado</strong></strong>.</li><li>Ejecuta <code>git remote -v</code>. Esto hace algo de magia usando <strong><strong><em><em>git pull</em></em></strong></strong> y <strong><strong><em><em>git push</em></em></strong></strong> para garantizar que el contenido de tu nuevo repositorio de Github y la carpeta en tu sistema local sean los mismos.</li><li>Finalmente, ejecuta <code>git push origin master</code> para empujar tus archivos a Github. Ten en cuenta que la última palabra<strong><em> </em></strong>en el comando <strong><strong><em><em>m</em></em></strong><em>aster</em></strong>, no es una entrada fija cuando se ejecuta <code>git push</code>, puede ser reemplazada por cualquier “nombre_de_rama” relevante.</li></ul><hr><p>¡Eso es todo! Sinceramente, creo que cualquiera puede aprender a programar. Pasé el año pasado dando clases particulares a estudiantes de pre-grado en Nigeria sobre Desarrollo de Software. </p><blockquote>¡Empieza hoy a programar!</blockquote><p>Traducido del artículo de <a href="https://www.freecodecamp.org/news/author/usheninte/"><strong>Usheninte Dangana</strong></a><strong><strong> - </strong><a href="https://www.freecodecamp.org/news/pushing-to-github-made-simple-enough-for-poets/">Pushing to Github - made simple enough for Poets</a></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Encadenamiento Opcional en JavaScript `?.` Explicado - Cómo Funciona y Cuándo Usarlo ]]>
                </title>
                <description>
                    <![CDATA[ Qué es el encadenamiento opcional? El encadenamiento opcional, representado por ?. en JavaScript, es una funcionalidad introducida en ES2020. El encadenamiento opcional cambia la forma en que se accede a las propiedades desde objetos profundamente anidados. Solucionando el problema de tener que comprobar elementos nulos múltiples veces al acceder a ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/encadenamiento-opcional-en-javascript-explicado/</link>
                <guid isPermaLink="false">5fdce02c8c7cd154bb97a022</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Fri, 25 Dec 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/04/photo-1425326452142-67c31f601d2f.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="qu-es-el-encadenamiento-opcional"><strong>Qué es el encadenamiento opcional?</strong></h2><p>El encadenamiento opcional, representado por <code>?.</code> en JavaScript, es una funcionalidad introducida en ES2020.</p><p>El encadenamiento opcional cambia la forma en que se accede a las propiedades desde objetos profundamente anidados. Solucionando el problema de tener que comprobar elementos nulos múltiples veces al acceder a una larga cadena de propiedades de objetos en JavaScript.</p><p>Estado Actual: <code>Propuesta de ECMAScript en la etapa 4 del proceso.</code> : <a href="https://github.com/tc39/proposal-optional-chaining">https://github.com/tc39/proposal-optional-chaining</a></p><h2 id="casos-de-uso"><strong>Casos de uso</strong></h2><ol><li>Acceder potencialmente a propiedades <code>null</code> o <code>undefined</code> de un objeto.</li><li>Obtener resultados de una variable que puede no estar disponible todavía.</li><li>Obtener valores predeterminados.</li><li>Acceder a largas cadenas de propiedades.</li></ol><p>Imagina que esperas que una API devuelva un objeto de este tipo:</p><pre><code class="language-javascript">obj = {
  prop1: {
    prop2: {
      algunaProp: "valor"
    }
  }
};</code></pre><p>Pero es posible que no sepas si cada uno de estos campos está disponible de antemano. Algunos de ellos pueden no haber sido devueltos por la API o pueden haber regresado con valores nulos.</p><p>Aquí hay un ejemplo:</p><pre><code class="language-javascript">//esperado
obj = {
  id: 9216,
  hijo: [
    { id: 123, hijo: null },
    { id: 124, hijo: [{ id: 1233, hijo: null }] }
  ]
};

//actual
obj = {
  id: 9216,
  hijo: null
};</code></pre><p>Esto sucede muy a menudo con funciones que llaman a una API. Es posible que hayas visto código en React que intenta protegerse contra estos problemas de la siguiente manera:</p><pre><code class="language-jsx">render = () =&gt; {
  const obj = {
    prop1: {
      prop2: {
        algunaProp: "valor",
      },
    },
  };

  return (
    &lt;div&gt;
      {obj &amp;&amp; obj.prop1 &amp;&amp; obj.prop1.prop2 &amp;&amp; obj.prop1.prop2.algunaProp &amp;&amp; (
        &lt;div&gt;{obj.prop1.prop2.algunaProp}&lt;/div&gt;
      )}
    &lt;/div&gt;
  );
};
</code></pre><p>Para afrontar mejor este problema, muchas veces en el pasado hemos utilizado <code>Lodash</code>, específicamente el método <code>_.get</code>:</p><pre><code class="language-javascript">_.get(obj, prop1.prop2.algunaProp);</code></pre><p>Esto genera <code>undefined</code> si alguna de esas propiedades es <code>undefined</code>. <strong><strong>¡El encadenamiento opcional es exactamente eso</strong></strong>! Ahora en lugar de utilizar una librería externa, esta funcionalidad está disponible de forma nativa.</p><h2 id="-c-mo-funciona-el-encadenamiento-opcional"><strong>¿Cómo funciona el encadenamiento opcional?</strong></h2><p><code>?.</code> se puede utilizar para encadenar propiedades que pueden ser <code>null</code> o <code>undefined</code>.</p><pre><code>const propNecesitada = obj?.prop1?.prop2?.algunaProp;</code></pre><p>Si cualquiera de esas propiedades encadenadas es <code>null</code> o <code>undefined</code>, JavaScript regresará <code>undefined</code>.</p><p>¿Qué pasa si queremos devolver algo más significativo? Prueba esto:</p><pre><code class="language-javascript">let arbolFamiliar = {
    nosotros: {
        hijo: {}
    }
}

// usando _.get
const nieto = _.get(arbolFamiliar, 'nosotros.hijo.suHijo', 'No se encontraron hijos' );

// usando encadenamiento opcional y null coalescing 
const nullCoalescing = arbolFamiliar?.nosotros?.hijo?.suHijo ?? 'No se encontraron hijos'

console.log(nullCoalescing) // No se encontraron hijos</code></pre><p>También funciona para objetos que pueden ser <code>null</code> o <code>undefined</code>:</p><pre><code>let usuario;
console.log(usuario?.id) // undefined</code></pre><h2 id="c-mo-obtener-esta-funcionalidad-tan-reciente"><strong>Cómo obtener esta funcionalidad tan reciente</strong></h2><ol><li>Pruébalo en la consola de tu navegador: Esta es una adición reciente y los navegadores antiguos pueden necesitar polyfills. Puedes probarlo en Chrome o Firefox desde la consola del navegador. Si no funciona, intenta activar las funciones experimentales de JavaScript visitando <code>chrome://flags/</code> y habilitando "JavaScript Experimental".</li><li>Pruébalo en una aplicación de Node usando Babel:</li></ol><pre><code>{
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}
</code></pre><h2 id="en-resumen"><strong>En resumen</strong></h2><p>Utiliza el encadenamiento opcional <code>?.</code> para comprobar objetos o propiedades en cadenas largas que pueden ser <code>null</code> o <code>undefined</code>. La sintaxis es la siguiente:</p><pre><code class="language-javascript">let usuario = {};
console.log(usuario?.id?.nombre)</code></pre><hr><p>¿Interesado en más tutoriales y JSBytes de mi parte? <a href="https://tinyletter.com/shrutikapoor">Suscríbete a mi boletín de noticias </a>o <a href="https://twitter.com/shrutikapoor08">sígueme en Twitter</a>.</p><p>Traducido del artículo de <strong><a href="https://www.freecodecamp.org/news/author/shrutikapoor08/"><strong>Shruti Kapoor</strong></a><strong> - </strong><a href="https://www.freecodecamp.org/news/javascript-optional-chaining-explained/">JavaScript Optional Chaining `?.` Explained - How it Works and When to Use it</a></strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Moderno – Imports, Exports, Let, Const, y Promesas en ES6+ ]]>
                </title>
                <description>
                    <![CDATA[ Durante los últimos años han habido muchas actualizaciones en el lenguaje de JavaScript. Siendo estas muy útiles para los que buscan mejorar como programador. Mantenerse al día con los nuevos desarrollos del lenguaje es realmente importante. Puede ayudarte a conseguir un trabajo mejor remunerado, mantenerte actualizado con las ultimas tendencias, ]]>
                </description>
                <link>https://www.freecodecamp.org/espanol/news/aprende-javascript-imports-exports-let-const-promisas-es6/</link>
                <guid isPermaLink="false">5fda78958c7cd154bb978062</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kelvin Sanchez ]]>
                </dc:creator>
                <pubDate>Fri, 25 Dec 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/espanol/news/content/images/2021/04/photo-1457305237443-44c3d5a30b89.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Durante los últimos años han habido muchas actualizaciones en el lenguaje de JavaScript. Siendo estas muy útiles para los que buscan mejorar como programador.</p><p>Mantenerse al día con los nuevos desarrollos del lenguaje es realmente importante. Puede ayudarte a conseguir un trabajo mejor remunerado, mantenerte actualizado con las ultimas tendencias, mejorar la calidad de tu código, y sobresalir en tu trabajo actual.</p><p>Y sin lugar a dudas necesitas conocer las funcionalides más recientes si estás tratando de aprender una librería de JavaScript como React o un framework como Angular o Vue.</p><p>Recientemente, el lenguaje de JavaScript ha recibido muchas adiciones útiles, como <strong>encadenamiento opcional</strong>, <strong>promesas</strong>, <strong><strong>async/await</strong></strong>, <strong>desestructuración</strong>, y más.</p><p>Hoy veremos algunos de estos conceptos, los cuales todo desarrollador de JavaScript debería conocer.</p><p>¡Empecemos!</p><h2 id="let-y-const-en-javascript"><strong>Let y const en JavaScript</strong></h2><p>Antes de ES6, JavaScript usaba la palabra clave <code>var</code> la cual solo cuenta con un ámbito global o funcional. El ámbito de bloque no existía.</p><p>Con la adición de <code>let</code> y <code>const</code> JavaScript incorporó este último.</p><h3 id="como-usar-let-en-javascript"><strong>Como usar let en JavaScript</strong></h3><p>Cuando declaramos una variable usando la palabra clave <code>let</code>, podemos <strong>asignar </strong>más tarde un nuevo valor a dicha variable, pero no podemos <strong>re-declararla</strong> con el mismo nombre.</p><pre><code class="language-js">// Código ES5
var valor = 10;
console.log(valor); // 10

var valor = "hola";
console.log(valor); // hola

var valor = 30;
console.log(valor); // 30
</code></pre><p>Como puedes ver arriba, hemos vuelto a declarar la variable <code>valor</code> usando la palabra clave <code>var</code> repetidas veces.</p><p>Antes de ES6, pudimos volver a declarar una variable que ya había sido declarada antes si esta no se usaba de manera significativa y en cambio causaba confusión.</p><p>Pero, ¿y si ya tuviéramos una variable declarada con el mismo nombre en otro lugar y la volvemos a declarar sin darnos cuenta? Entonces podríamos sobrescribir el valor de la variable, causando algunos problemas difíciles de depurar.</p><p>Usando la palabra clave <code>let</code>, si intentas volver a declarar la variable con el mismo nombre obtendrás un error – lo cual es bueno.</p><pre><code class="language-js">// Código ES6
let valor = 10;
console.log(valor); // 10

let valor = "hola"; // Uncaught SyntaxError: Identifier 'valor' has already been declared
</code></pre><p>Pero, el siguiente código es válido:</p><pre><code class="language-js">// Código ES6
let valor = 10;
console.log(valor); // 10

valor = "hola";
console.log(valor); // hola
</code></pre><p>No obtenemos un error en el código anterior porque estamos <strong><strong>re-as</strong>ignando</strong> un nuevo valor a la variable <code>valor</code>. Pero <strong>no </strong>estamos<strong> re-declarando</strong> <code>valor</code> de nuevo.</p><p>Ahora, observa el siguiente código:</p><pre><code class="language-js">// Código ES5
var esValido = true;
if(esValido) {
  var numero = 10;
  console.log('dentro:', numero); // dentro: 10
}
console.log('fuera:', numero); // fuera: 10
</code></pre><p>Como puedes ver en este código, cuando declaramos una variable con la palabra clave <code>var</code>, esta se encuentra disponible dentro y fuera del bloque <code>if</code>.</p><p>Ahora, observa el siguiente código:</p><pre><code class="language-js">// ES6 Code
let esValido = true;
if(esValido) {
  let numero = 10;
  console.log('dentro:', numero); // dentro: 10
}

console.log('fuera:', numero); // Uncaught ReferenceError: numero is not defined
</code></pre><p>Como puedes ver, al declarar la variable <code>numero</code> usando la palabra clave <code>let</code> esta solo es accesible dentro del bloque <code>if</code>. No está disponible fuera del bloque, por lo que obtuvimos un error de referencia cuando intentamos acceder a ella fuera del bloque <code>if</code>.</p><p>Pero si hay una variable <code>numero</code> fuera del bloque <code>if</code>, funcionará como se muestra a continuación:</p><pre><code class="language-js">// Código ES6
let esValido = true;
let numero = 20;

if(esValido) {
  let numero = 10;
  console.log('dentro:', numero); // dentro: 10
}

console.log('fuera:', numero); // fuera: 20
</code></pre><p>En este caso tenemos dos variables <code>numero</code> con un ámbito distinto. Por lo que fuera del bloque <code>if</code>, el valor <code>numero</code> será 20.</p><p>Observa el siguiente código:</p><pre><code class="language-js">// Código ES5
for(var i = 0; i &lt; 10; i++){
 console.log(i);
}
console.log('fuera:', i); // 10
</code></pre><p>Al usar la palabra clave <code>var</code>, <code>i</code> está disponible incluso fuera del bucle <code>for</code>.</p><pre><code class="language-js">// Código ES6
for(let i = 0; i &lt; 10; i++){
 console.log(i);
}

console.log('fuera:', i); // Uncaught ReferenceError: i is not defined
</code></pre><p>En cambio al usar <code>let</code>, esta no está disponible fuera del bucle.</p><p>Entonces como pudiste ver en los ejemplos de código anteriores, usar <code>let</code> hace la variable accesible solo dentro de ese bloque y no desde fuera del mismo. </p><p>También podemos crear un bloque con un par de llaves como esta:</p><pre><code class="language-js">let i = 10;
{
 let i = 20;
 console.log('dentro:', i); // dentro: 20
 i = 30;
 console.log('i de nuevo:', i); // i de nuevo: 30
}

console.log('fuera:', i); // fuera: 10
</code></pre><p>Si recuerdas, comenté que no podemos re-declarar una variable basada en <code>let</code> en el mismo bloque, pero podemos re-declararla en otro bloque. Como puedes ver en el código anterior, re-declaramos <code>i</code> y asignamos un nuevo valor de <code>20</code> dentro del bloque. Una vez declarada, ese valor de la variable estará disponible solo en ese bloque.</p><p>Fuera del bloque, cuando imprimimos esa variable, obtuvimos <code>10</code> en lugar de <code>30</code> que fue el valor previamente asignado, ya que fuera del bloque la variable interior <code>i</code> no existe.</p><p>Si no tenemos la variable <code>i</code> declarada afuera, obtendremos un error como puedes ver en el siguiente código:</p><pre><code class="language-js">{
 let i = 20;
 console.log('dentro:', i); // dentro: 20
 i = 30;
 console.log('i de nuevo:', i); // i de nuevo: 30
}

console.log('fuera:', i); // Uncaught ReferenceError: i is not defined
</code></pre><h3 id="como-usar-const-en-javascript"><strong>Como usar const en JavaScript</strong></h3><p>La palabra clave <code>const</code> funciona exactamente igual que la palabra clave <code>let</code> en cuanto a su ámbito de bloque. Así que veamos cómo se diferencian entre sí.</p><p>Cuando declaramos una variable como <code>const</code>, esta se considera una variable constante cuyo valor nunca cambiará.</p><p>En el caso de <code>let</code>, podemos asignar mas adelante un nuevo valor a esa variable de esta manera:</p><pre><code class="language-js">let numero = 10;
numero = 20;

console.log(numero); // 20
</code></pre><p>Pero no podemos hacer eso en el caso de <code>const</code>:</p><pre><code class="language-js">const numero = 10;
numero = 20; // Uncaught TypeError: Assignment to constant variable.
</code></pre><p>Ni siquiera podemos <strong>re-declarar</strong> una variable <code>const</code>.</p><pre><code class="language-js">const numero = 20;
console.log(numero); // 20

const numero = 10; // Uncaught SyntaxError: Identifier 'numero' has already been declared
</code></pre><p>Ahora, observa el siguiente código:</p><pre><code class="language-js">const arr = [1, 2, 3, 4];

arr.push(5);

console.log(arr); // [1, 2, 3, 4, 5]
</code></pre><p>Hemos dicho que la variable <code>const</code> es una constante cuyo valor nunca cambiará – pero acabamos de hacer un cambio en un arreglo definido como constante. Entonces, ¿qué sentido tiene eso?</p><blockquote>Nota: En JavaScript los arreglos son de tipo referencia y no de tipo primitivo.</blockquote><p>Así que lo que realmente se almacena en <code>arr</code> no es el arreglo real, sino una referencia (dirección) de la ubicación en la memoria donde se encuentra almacenado el arreglo real.</p><p>Entonces haciendo <code>arr.push(5);</code> no estamos cambiando la referencia a la que apunta <code>arr</code>, pero estamos cambiando los valores almacenados en ella.</p><p>Con objetos tenemos el mismo caso:</p><pre><code class="language-js">const obj = {
 nombre: 'David',
 edad: 30
};

obj.edad = 40;

console.log(obj); // { nombre: 'David', edad: 40 }
</code></pre><p>Aquí tampoco estamos cambiando la referencia donde apunta <code>obj</code>, sino los valores almacenados en ella.</p><p>De tal manera que el código anterior funcionará, pero el siguiente no.</p><pre><code class="language-js">const obj = { nombre: 'David', edad: 30 };
const obj1 = { nombre: 'Mike', edad: 40 };
obj = obj1; // Uncaught TypeError: Assignment to constant variable.
</code></pre><p>El código anterior no funciona porque estamos intentando cambiar la referencia a la que apunta la variable <code>const</code>.</p><p>Así que el punto clave a recordar cuando usamos <code>const</code> es que, si declaramos la variable como constante, no podemos re-definirla. Tampoco podemos re-asignar esa variable, pero podemos cambiar los valores almacenados en la misma si esta es de tipo referencia.</p><p>Por lo tanto, el siguiente código no es válido porque le estamos reasignando un nuevo valor.</p><pre><code class="language-js">const arr = [1, 2, 3, 4];
arr = [10, 20, 30]; // Uncaught TypeError: Assignment to constant variable.
</code></pre><p>Pero ten en cuenta que podemos cambiar los valores dentro del arreglo, como vimos anteriormente.</p><p>El siguiente código para re-definir una variable <code>const</code> también es inválido.</p><pre><code class="language-js">const nombre = "David";
const nombre = "Raj"; // Uncaught SyntaxError: Identifier 'nombre' has already been declared
</code></pre><h3 id="resumen-de-let-y-const"><strong>Resumen de let y const</strong></h3><ul><li>Las palabras claves <code>let</code> y <code>const</code> añaden ámbito de bloque en JavaScript.</li><li>Cuando declaramos una variable como <code>let</code>, no podemos <strong>re-definir</strong> o <strong>re-declarar</strong> otra variable <code>let</code> con el mismo nombre en el mismo ámbito (funcional o de bloque). Pero podemos <strong>re-asignar </strong>un valor a ella.</li><li>Cuando declaramos una variable como <code>const</code>, no podemos <strong>re-definir</strong> o <strong>re-declarar</strong> otra variable <code>const</code> con el mismo nombre en el mismo ámbito (funcional o de bloque). Pero podemos cambiar los valores almacenados en dicha variable, si esta es de tipo referencia, como un arreglo u objeto.</li></ul><p>Muy bien, pasemos al siguiente gran tema: promesas.</p><h2 id="promesas-en-javascript"><strong>Promesas en JavaScript</strong></h2><p>Las promesas son una de las partes más importantes, aunque confusas y difíciles de entender de JavaScript. Y la mayoría de los desarrolladores nuevos, así como los experimentados, luchan por comprenderlas.</p><p>Las promesas se añadieron en ES6 de forma nativa.</p><p>Entonces, ¿qué es una promesa? Una promesa representa una operación asincrónica que se completará en el futuro.</p><p>Anteriormente, antes de ES6, no había forma de esperar por algo que realizara alguna operación.</p><p>Por ejemplo, cuando queríamos hacer una llamada a la API, no había forma de esperar hasta que los resultados llegaran.</p><p>Para eso, solíamos usar bibliotecas externas como Jquery o Ajax que tenían su propia implementación de promesas. Pero el navegador no contaba nativamente con dichas funciones.</p><p>Pero ahora, usando Promesas en ES6, podemos hacer una llamada a la API por nuestra cuenta y esperar hasta que esté lista para realizar alguna operación.</p><h3 id="como-crear-una-promesa"><strong>Como crear una Promesa</strong></h3><p>Para crear una promesa, necesitamos usar la función constructora <code>Promise</code> de la siguiente forma:</p><pre><code class="language-js">const promesa = new Promise(function(resolver, rechazar) {
 
});
</code></pre><p>El constructor <code>Promise</code> toma una función como argumento y dicha función recibe internamente <code>resolver</code> y <code>rechazar</code> como parámetros.</p><p>Los parámetros <code>resolver</code> y <code>rechazar</code> son en realidad funciones que podemos llamar dependiendo del resultado de la operación asincrónica.</p><p>Una promesa <code>Promise</code> pasa por tres estados:</p><ul><li>Pendiente</li><li>Cumplido</li><li>Rechazado</li></ul><p>Cuando creamos una promesa, la misma está en estado pendiente. Al llamar a la función <code>resolver</code>, entra en estado cumplido y si llamamos <code>rechazar</code>, pasará al estado rechazado.</p><p>Para simular una operación asíncrona o de larga duración, usaremos la función <code>setTimeout</code>.</p><pre><code class="language-js">const promesa = new Promise(function(resolver, rechazar) {
 setTimeout(function() {
  const suma = 4 + 5;
  resolver(suma);
 }, 2000);
});
</code></pre><p>Aquí creamos una promesa que se resolverá con la suma de <code>4</code> y <code>5</code> después de que finalice un tiempo de espera de 2000 ms (2 segundos).</p><p>Para obtener el resultado de la ejecución exitosa de la promesa, necesitamos registrar un callback usando <code>.then</code> de la siguiente manera:</p><pre><code class="language-js">const promesa = new Promise(function(resolver, rechazar) {
 setTimeout(function() {
  const suma = 4 + 5;
  resolver(suma);
 }, 2000);
});

promesa.then(function(resultado) {
 console.log(resultado); // 9
});
</code></pre><p>Entonces, cada vez que llamemos <code>resolver</code>, la promesa devolverá el valor transmitido a la función, el cual podemos recopilar usando el manejador <code>.then</code>.</p><p>Si la operación no tiene éxito, llamamos a la función <code>rechazar</code> así:</p><pre><code class="language-js">const promesa = new Promise(function(resolver, rechazar) {
 setTimeout(function() {
  const suma = 4 + 5 + 'a';
  if(isNaN(suma)) {
    rechazar('Error al calcular la suma.');
  } else {
    resolver(suma);
  }
 }, 2000);
});

promesa.then(function(resultado) {
 console.log(resultado);
});
</code></pre><p>Aquí, si la <code>suma</code> no es un número, llamamos a la función <code>rechazar</code> con el mensaje de error. De lo contrario, llamamos a la función <code>resolver</code>.</p><p>Si ejecutas el código anterior, verás el siguiente resultado:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://gist.github.com/myogeshchavan97/e0be7fc4c838544e2d00afeb3a82ae10/raw/9adf1d42d876e2b87ef0ecfbf97b06a01c026eba/error_no_catch.png" class="kg-image" alt="Error without catch" width="600" height="400" loading="lazy"></figure><p>Como puedes ver, obtenemos un mensaje de error sin captar junto al mensaje que especificamos, porque llamar a la función <code>rechazar</code> arroja un error. Pero no hemos agregado un manejador de errores para captar dicho error.</p><p>Para captar el error, necesitamos registrar otro callback usando <code>.catch</code> de esta forma:</p><pre><code class="language-js">promesa.then(function(resultado) {
 console.log(resultado);
}).catch(function(error) {
 console.log(error);
});
</code></pre><p>Verás la siguiente salida:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://gist.github.com/myogeshchavan97/e0be7fc4c838544e2d00afeb3a82ae10/raw/9adf1d42d876e2b87ef0ecfbf97b06a01c026eba/error_catch.png" class="kg-image" alt="Error with catch" width="600" height="400" loading="lazy"></figure><p>Como puedes ver, hemos agregado el manejador <code>.catch</code>, por lo que no obtenemos ningún error sin captar, solo estamos registrando el error en la consola.</p><p>Esto también evita que tu aplicación se detenga abruptamente.</p><p>Por lo tanto, se recomienda siempre agregar el manejador <code>.catch</code> a cada promesa para que la aplicación no deje de ejecutarse debido a un error.</p><h3 id="encadenamiento-de-promesas"><strong>Encadenamiento de promesas</strong></h3><p>Podemos agregar multiples manejadores <code>.then</code> a una sola promesa de la siguiente manera:</p><pre><code class="language-js">promesa.then(function(resultado) {
 console.log('Primer manejador .then');
 return resultado;
}).then(function(resultado) {
 console.log('Segundo manejador .then');
 console.log(resultado);
}).catch(function(error) {
 console.log(error);
});
</code></pre><p>Cuando tenemos agregados múltiples manejadores <code>.then</code>, el valor devuelto por el anterior es traspasado automáticamente al siguiente.</p><figure class="kg-card kg-image-card"><img src="https://gist.github.com/myogeshchavan97/e0be7fc4c838544e2d00afeb3a82ae10/raw/9adf1d42d876e2b87ef0ecfbf97b06a01c026eba/promise_chaining.png" class="kg-image" alt="Promise Chaining" width="600" height="400" loading="lazy"></figure><p>Como puedes ver, al sumar <code>4 + 5</code> se resuelve una promesa, y obtenemos el resultado de la suma en el primer manejador <code>.then</code>. Allí imprimimos un mensaje en la consola y devolvemos el resultado al siguiente <code>.then</code>.</p><p>Dentro del siguiente manejador <code>.then</code>, agregamos una declaración de consola e imprimimos el resultado que obtuvimos del manejador <code>.then</code> anterior.</p><p>Este patrón de agregar múltiples manejadores <code>.then</code> de forma consecutiva se conoce como encadenamiento de promesas.</p><h3 id="c-mo-retrasar-la-ejecuci-n-de-una-promesa-en-javascript">Cómo retrasar la ejecución de una promesa en JavaScript</h3><p>Muchas veces no queremos crear una promesa de inmediato, sino que queremos crear una después de que se complete alguna operación.</p><p>Para lograr esto, podemos envolver la promesa en una función y devolver esa promesa desde dicha función de esta manera:</p><pre><code class="language-js">function crearPromesa() {
 return new Promise(function(resolver, rechazar) {
  setTimeout(function() {
   const suma = 4 + 5;
   if(isNaN(suma)) {
     rechazar('Error al calcular la suma.');
   } else {
    resolver(suma);
   }
  }, 2000);
 });
}
</code></pre><p>De esta manera, podemos usar los parámetros de la función dentro de la promesa, haciendo que la función sea verdaderamente dinámica.</p><pre><code class="language-js">function crearPromesa() {
 return new Promise(function(resolver, rechazar) {
  setTimeout(function() {
   const suma = 4 + 5;
   if(isNaN(suma)) {
     rechazar('Error al calcular la suma.');
   } else {
    resolver(suma);
   }
  }, 2000);
 });
}

crearPromesa(1,8)
 .then(function(resultado) {
  console.log(resultado); // 9
});

// OR

crearPromesa(10,24)
 .then(function(resultado) {
  console.log(resultado); // 34
});
</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://gist.github.com/myogeshchavan97/e0be7fc4c838544e2d00afeb3a82ae10/raw/9adf1d42d876e2b87ef0ecfbf97b06a01c026eba/general_function.png" class="kg-image" alt="Output" width="600" height="400" loading="lazy"></figure><p><strong><strong>Not</strong>a<strong>:</strong></strong> Cuando creamos una promesa, se resolverá o rechazará, pero no ambas al mismo tiempo. Por lo tanto, no podemos agregar dos llamadas a la función <code>resolver</code> o <code>rechazar</code> en la misma promesa.</p><p>Además, podemos pasar solo un valor a la función <code>resolver</code> o <code>rechazar</code>.</p><p>Si deseas pasar varios valores a una función <code>resolver</code>, puedes utilizar un objeto como en el siguiente ejemplo:</p><pre><code class="language-js">const promesa = new Promise(function(resolver, rechazar) {
 setTimeout(function() {
  const suma = 4 + 5;
  resolver({
   a: 4,
   b: 5,
   suma
  });
 }, 2000);
});

promesa.then(function(resultado) {
 console.log(resultado);
}).catch(function(error) {
 console.log(error);
});
</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://gist.github.com/myogeshchavan97/e0be7fc4c838544e2d00afeb3a82ae10/raw/65fba14b45b22228f49107634d440903eb0c8dbd/object_resolve.png" class="kg-image" alt="Resolving object" width="600" height="400" loading="lazy"></figure><h3 id="c-mo-usar-las-funciones-de-flecha-en-javascript">Cómo usar las funciones de flecha en JavaScript</h3><p>En todos los ejemplos de código pasados, al crear promesas utilizamos la sintaxis regular de función en ES5. Pero en su lugar, es común usar la sintaxis de función de flecha de la siguiente manera.</p><pre><code class="language-js">const promesa = new Promise((resolver, rechazar) =&gt; {
 setTimeout(() =&gt; {
  const suma = 4 + 5 + 'a';
  if(isNaN(suma)) {
    rechazar('Error al calcular la suma.');
  } else {
    resolver(suma);
  }
 }, 2000);
});

promesa.then((resultado) =&gt; {
 console.log(resultado);
});
</code></pre><p>Puedes utilizar la sintaxis de función en ES5 o ES6 dependiendo de tus preferencias y necesidades.</p><h2 id="sintaxis-para-import-y-export-en-es6"><strong>Sintaxis para Import y Export en ES6</strong></h2><p>Antes de que ES6 entrara en juego, utilizabamos múltiples etiquetas <code>script</code> en un solo archivo HTML para importar diferentes archivos JavaScript de esta manera:</p><pre><code class="language-js">&lt;script type="text/javascript" src="inicio.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="perfil.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="usuario.js"&gt;&lt;/script&gt;
</code></pre><p>Entonces, si existiese una variable con el mismo nombre en diferentes archivos JavaScript, se crearía un conflicto de nombres y el valor que esperabas no sería el valor real que obtuviste.</p><p>ES6 ha solucionado este problema con el concepto de módulos.</p><p>Cada archivo JavaScript que escribimos en ES6 se conoce como módulo. Las variables y funciones que declaramos en cada archivo no están disponibles para otros archivos hasta que las exportamos específicamente desde ese archivo y las importamos a otro.</p><p>Por lo tanto, las funciones y variables definidas en el archivo son privadas para cada uno, y no se pueden acceder desde fuera hasta que las exportemos.</p><p>Hay dos tipos de exportaciones:</p><ul><li>Exportaciones Nombradas: Pueden haber múltiples exportaciones con nombre en un solo archivo</li><li>Exportaciones por Defecto: Solo puede haber una exportación por defecto en un solo archivo</li></ul><h3 id="exportaciones-nombradas-en-javascript"><strong>Exportaciones Nombradas en JavaScript</strong></h3><p>Para exportar un solo valor como una exportación nombrada, lo exportamos así:</p><pre><code class="language-js">export const temp = "Este es un texto ficticio";
</code></pre><p>Si tenemos varias cosas para exportar, podemos escribir una declaración de exportación en una línea separada en lugar de delante de la declaración de variable. Especificamos las cosas a exportar entre llaves.</p><pre><code class="language-js">const temp1 = "Este es un texto ficticio1";
const temp2 = "Este es un texto ficticio2";

export { temp1, temp2 };
</code></pre><p>Ten en cuenta que la sintaxis de exportación no es una sintaxis literal de objeto. Por lo que, en ES6, para exportar algo no podemos usar pares clave-valor como el siguiente:</p><pre><code class="language-js"> // Esta es una sintaxis de exportación no válida en ES6

export { clave1: valor1, clave2: valor2 }
</code></pre><p>Para importar las cosas que exportamos como una exportación nombrada, usamos la siguiente sintaxis:</p><pre><code class="language-js">import { temp1, temp2 } from './nombreDelArchivo';
</code></pre><p>Ten en cuenta que al importar algo desde un archivo, no es necesario agregar la extensión <code>.js</code> al nombre del mismo, ya que se considera de forma predeterminada.</p><pre><code class="language-js">// importar desde el archivo funciones.js desde el directorio actual 
import { temp1, temp2 } from './funciones';

// importar desde el archivo funciones.js desde el padre del directorio actual
import { temp1 } from '../funciones';
</code></pre><p>Aquí hay una demostración en Code Sandbox: <a href="https://codesandbox.io/s/hardcore-pond-q4cjx">https://codesandbox.io/s/hardcore-pond-q4cjx</a></p><p><strong>Una cosa a tener en cuenta es que el nombre utilizado durante la exportación debe coincidir con el nombre que utilizamos durante la importación.</strong></p><p>Por lo que, si estás exportando así:</p><pre><code class="language-js">// constantes.js
export const PI = 3.14159;
</code></pre><p>Luego, al importar, debes usar el mismo nombre que usaste al exportar:</p><pre><code class="language-js">import { PI } from './constantes';
</code></pre><p>No puedes usar ningún otro nombre como este:</p><pre><code class="language-js">import { ValorPI } from './constantes'; // Esto arrojará un error
</code></pre><p>Pero si ya tienes la variable con el mismo nombre que la variable exportada, puedes usar la siguiente sintaxis para renombrar la variable mientras realizas la importación:</p><pre><code class="language-js">import { PI as ValorPI } from './constantes';
</code></pre><p>Aquí hemos cambiado el nombre de <code>PI</code> a <code>ValorPI</code> y por lo tanto ya no podemos usar el nombre <code>PI</code> como variable. En su lugar, tenemos que usar la variable <code>ValorPI</code> para obtener el valor exportado de <code>PI</code>.</p><p>También podemos utilizar la sintaxis de cambio de nombre a la hora de exportar:</p><pre><code class="language-js">// constantes.js
const PI = 3.14159; 

export { PI as ValorPI };
</code></pre><p>Luego, al importar, tenemos que usar <code>ValorPI</code> así:</p><pre><code class="language-js">import { ValorPI } from './constantes';
</code></pre><p>Para exportar algo como una exportación nombrada, primero debemos declararlo.</p><pre><code class="language-js">export 'hola'; // Esto arrojará un error
export const saludos = 'hola'; // Esto funcionará
export { nombre: 'David' }; // Esto arrojará un error
export const objeto = { nombre: 'David' }; // Esto funcionará
</code></pre><p><strong>El orden en el que importamos las múltiples exportaciones nombradas no es importante.</strong></p><p>Fíjate en el siguiente archivo <code>validations.js</code>:</p><pre><code class="language-js">// utils/validations.js

const esEmailValido = function(email) {
  if (/^[^@ ]+@[^@ ]+\.[^@ \.]{2,}$/.test(email)) {
    return "el email es válido";
  } else {
    return "el email es inválido";
  }
};

const esTelefonoValido = function(telefono) {
  if (/^[\\(]\d{3}[\\)]\s\d{3}-\d{4}$/.test(telefono)) {
    return "el número de teléfono es válido";
  } else {
    return "el número de teléfono es inválido";
  }
};

function estaVacia(valor) { 
  if (/^\s*$/.test(valor)) {
    return "la cadena está vacía o contiene solo espacios";
  } else {
    return "la cadena no está vacía y no contiene espacios";
  } 
}

export { esEmailValido, esTelefonoValido, estaVacia };
</code></pre><p>Y en <code>index.js</code> usamos estas funciones como se muestra a continuación:</p><pre><code class="language-js">// index.js
import { estaVacia, esEmailValido } from "./utils/validations";

console.log("estaVacia:", estaVacia("abcd")); // estaVacia: la cadena no está vacía y no contiene espacios

console.log("esEmailValido:", esEmailValido("abc@11gmail.com")); // esEmailValido: el email es válido

console.log("esEmailValido:", esEmailValido("ab@c@11gmail.com")); // esEmailValido: el email es inválido
</code></pre><p>Aquí hay una demostración en Code Sandbox: <a href="https://codesandbox.io/s/youthful-flower-xesus">https://codesandbox.io/s/youthful-flower-xesus</a></p><p>Como puedes ver, pudimos importar solo los elementos exportados requeridos y en cualquier orden, por lo que no es necesario verificar en qué orden fueron exportados en otro archivo. Esa es la belleza de las exportaciones nombradas.</p><h3 id="exportaciones-por-defecto-en-javascript"><strong>Exportaciones por Defecto en JavaScript</strong></h3><p>Como dije anteriormente, puede haber como máximo una exportación por defecto en un solo archivo.</p><p>Sin embargo, puedes combinar varias exportaciones nombradas y una exportación por defecto en un solo archivo.</p><p>Para declarar una exportación por defecto, agregamos la palabra clave <code>default</code> &nbsp;delante de la palabra clave <code>export</code> de la siguiente manera:</p><pre><code class="language-js">//constantes.js
const nombre = 'David'; 
export default nombre;
</code></pre><p>Para importar la exportación por defecto, no agregamos llaves como hicimos en la exportación nombrada, en cambio lo hacemos así:</p><pre><code class="language-js">import nombre from './constantes';
</code></pre><p>Si tenemos varias exportaciones nombradas y una exportación por defecto como esta:</p><pre><code class="language-js">// constantes.js
export const PI = 3.14159; 
export const EDAD = 30;

const NOMBRE = "David";
export default NOMBRE;
</code></pre><p>Luego, para importar todo en una sola línea, necesitamos usar la variable exportada por defecto antes del corchete.</p><pre><code class="language-js">// NOMBRE es una exportación por defecto y PI y Edad son exportaciones nombradas

import NOMBRE, { PI, EDAD } from './constantes';
</code></pre><p><strong>Una especialidad de la exportación por defecto es que podemos cambiar el nombre de la variable exportada durante la importación:</strong></p><pre><code class="language-js">// constantes.js
const EDAD = 30;
export default EDAD;
</code></pre><p>Y en otro archivo, podemos usar otro nombre al importar</p><pre><code class="language-js">import miEdad from ‘./constantes’; 

console.log(miEdad); // 30
</code></pre><p>Aquí, hemos cambiado el nombre de la variable exportada por defecto de <code>EDAD</code> a <code>miEdad</code>.</p><p>Esto funciona porque solo puede haber una exportación por defecto, por lo que puedes nombrarla como desees.</p><p>Otra cosa a tener en cuenta sobre la exportación por defecto es que la palabra clave <code>export default</code> no puede ir antes de la declaración de una variable como esta:</p><pre><code class="language-js">// constantes.js
export default const EDAD = 30; // Este es un error y no funcionará
</code></pre><p>Así que tenemos que usar la palabra clave <code>export default</code> en una línea separada de esta forma:</p><pre><code class="language-js">// constantes.js 

const EDAD = 30; 
export default EDAD;
</code></pre><p>Sin embargo, podemos exportar por defecto sin declarar la variable de esta manera:</p><pre><code class="language-js">//constantes.js
export default {
 nombre: "Billy",
 edad: 40
};
</code></pre><p>Y en otro archivo usarlo así:</p><pre><code class="language-js">import usuario from './constantes';
console.log(usuario.nombre); // Billy 
console.log(usuario.edad); // 40
</code></pre><p>Existe otra forma de importar todas las variables exportadas en un archivo usando la siguiente sintaxis:</p><pre><code class="language-js">import * as constantes from './constantes';
</code></pre><p>Aquí, estamos importando todas las exportaciones nombradas y por defecto que tenemos en <code>constantes.js</code> y estas se almacenaran en la variable <code>constantes</code>. Así que, <code>constantes</code> se convertirá en un objecto.</p><pre><code class="language-js">// constantes.js
export const USERNAME = "David";
export default {
 nombre: "Billy",
 edad: 40
};
</code></pre><p>Y en otro archivo, lo usamos de la siguiente manera:</p><pre><code class="language-js">// prueba.js

import * as constantes from './constantes';

console.log(constantes.USERNAME); // David
console.log(constantes.default); // { nombre: "Billy", edad: 40 }
console.log(constantes.default.edad); // 40
</code></pre><p>Aquí hay una demostración en Code Sandbox: <a href="https://codesandbox.io/s/green-hill-dj43b">https://codesandbox.io/s/green-hill-dj43b</a></p><p>Si no deseas exportar en líneas separadas las exportaciones por defecto y nombradas, puedes combinarlas como se muestra a continuación:</p><pre><code class="language-js">// constantes.js
const PI = 3.14159; const EDAD = 30;
const USERNAME = "David";
const USUARIO = {
 nombre: "Billy",
 edad: 40 
};

export { PI, EDAD, USERNAME, USUARIO as default };
</code></pre><p>Aquí, estamos exportando USUARIO como exportación por defecto y las otras como exportaciones nombradas.</p><p>En otro archivo, puedes usarlo así:</p><pre><code class="language-js">import USUARIO, { PI, EDAD, USERNAME } from "./constantes";
</code></pre><p>Aquí hay una demostración en Code Sandbox: <a href="https://codesandbox.io/s/eloquent-northcutt-7btp1">https://codesandbox.io/s/eloquent-northcutt-7btp1</a></p><h3 id="en-resumen-"><strong>En resumen:</strong></h3><ol><li>En ES6, los datos declarados en un archivo no son accesibles a otro archivo hasta que se exportan desde ese archivo y se importan a otro archivo.</li><li>Si tenemos una sola cosa para exportar en un archivo como una declaración de clase, usamos la exportación por defecto, de lo contrario usamos la exportación nombrada. También podemos combinar exportaciones por defecto y nombradas en un solo archivo.</li></ol><h2 id="par-metros-predeterminados-en-javascript"><strong>Parámetros Predeterminados en JavaScript</strong></h2><p>ES6 ha agregado una característica bastante útil para proporcionar parámetros predeterminados al definir funciones.</p><p>Supongamos que tenemos una aplicación, donde una vez que el usuario inicia sesión en el sistema, les mostramos un mensaje de bienvenida como este:</p><pre><code class="language-js">function mostrarMensaje(primerNombre) {
  return "Bienvenido de nuevo, " + primerNombre;
}
console.log(mostrarMensaje('John')); // Bienvenido de nuevo, John
</code></pre><p>Pero, ¿qué pasa si no tenemos el nombre de usuario en nuestra base de datos, ya que era un campo opcional al momento de registrarse? Entonces podemos mostrar un mensaje al usuario como: <code>Bienvenido Invitado</code> después de iniciar sesión.</p><p>Así que, primero debemos verificar si se proporciona el <code>primerNombre</code> y luego mostrar el mensaje correspondiente. Antes de ES6, habríamos tenido que escribir un código como este:</p><pre><code class="language-js">function mostrarMensaje(primerNombre) {
  if(primerNombre) {
    return "Bienvenido de nuevo, " + primerNombre;
  } else {
    return "Bienvenido de nuevo, Invitado";
  }
}

console.log(mostrarMensaje('John')); // Bienvenido de nuevo, John 
console.log(mostrarMensaje()); // Bienvenido de nuevo, Invitado
</code></pre><p>Pero ahora en ES6 usando los parámetros de función predeterminados, podemos escribir el código anterior como se muestra a continuación:</p><pre><code class="language-js">function mostrarMensaje(primerNombre = 'Invitado') {
   return "Bienvenido de nuevo, " + primerNombre;
}

console.log(mostrarMensaje('John')); // Bienvenido de nuevo, John 
console.log(mostrarMensaje()); // Bienvenido de nuevo, Invitado
</code></pre><p><strong>Podemos asignar cualquier valor como predeterminado al parámetro de la función.</strong></p><pre><code class="language-js">function mostrar(a = 10, b = 20, c = b) { 
 console.log(a, b, c);
}

mostrar(); // 10 20 20
mostrar(40); // 40 20 20
mostrar(1, 70); // 1 70 70
mostrar(1, 30, 70); // 1 30 70
</code></pre><p>Como puedes ver, hemos asignado valores únicos a los parámetros de la función a y b, pero para c estamos asignando el valor de b. Entonces, cualquier valor que hayamos proporcionado para b se asignará a c también si no se proporciona un valor específico para c al llamar a la función.</p><p>En el código anterior, no hemos proporcionado todos los argumentos a la función. Entonces, las llamadas a las funciones anteriores serán las mismas que las siguientes:</p><pre><code class="language-js">mostrar(); // es igual que mostrar(undefined, undefined, undefined)
mostrar(40); // es igual que mostrar(40, undefined, undefined)
mostrar(1, 70); // es igual que mostrar(1, 70, undefined)
</code></pre><p>De tal manera que, si el argumento pasado es <code>undefined</code>, el valor predeterminado se usará para el parámetro correspondiente.</p><p><strong>También podemos asignar valores complejos o calculados como valor predeterminado.</strong></p><pre><code class="language-js">const usuarioPredeterminado = {
  nombre: 'Jane',
  ubicacion: 'NY',
  trabajo: 'Desarrolladora de Software'
};

const mostrar = (usuario = usuarioPredeterminado, edad = 60 / 2 ) =&gt; { 
 console.log(usuario, edad);
};
mostrar();

/* resultado:

{
  nombre: 'Jane',
  ubicacion: 'NY',
  trabajo: 'Software Developer'
} 30 

*/
</code></pre><p>Ahora, da un vistazo al siguiente código en ES5:</p><pre><code class="language-js">// Código ES5
function obtenerUsuarios(pagina, resultados, genero, nacionalidad) {
  var parametros = "";
  if(pagina === 0 || pagina) {
   parametros += `page=${pagina}&amp;`; 
  }
  if(resultados) {
   parametros += `results=${resultados}&amp;`;
  }
  if(genero) {
   parametros += `gender=${genero}&amp;`;
  }
  if(nacionalidad) {
   parametros += `nationality=${nacionalidad}`;
  }

  fetch('https://randomuser.me/api/?' + parametros) 
   .then(function(respuesta) {
     return respuesta.json(); 
   })
   .then(function(resultado) { 
    console.log(resultado);
   }) 
   .catch(function(error) {
     console.log('error', error); 
   }); 
}

obtenerUsuarios(0, 10, 'male', 'us');
</code></pre><p>En este código, estamos haciendo una llamada API al usuario aleatorio (<a href="https://randomuser.me/">Random user</a>) pasando varios parámetros opcionales en la función <code>obtenerUsuarios</code>.</p><p>Entonces, antes de realizar la llamada API, hemos agregado varias condiciones if para verificar si el parámetro se agrega o no, y en base a eso, construimos una cadena de consulta de la siguiente manera: <code>https://randomuser.me/api/?page=0&amp;results=10&amp;gender=male&amp;nationality=us</code>.</p><p>Pero en lugar de agregar tantas condiciones if, podemos usar los parámetros predeterminados mientras definimos los parámetros de la función como se muestra a continuación:</p><pre><code class="language-js">function obtenerUsuarios(pagina = 0, resultados = 10, genero = 'male', nacionalidad = 'us') {
 fetch(`https://randomuser.me/api/?page=${pagina}&amp;results=${resultados}&amp;gender=${genero}&amp;nationality=${nacionalidad}`)
 .then(function(respuesta) { 
  return respuesta.json();
 }) 
 .then(function(resultado) {
   console.log(resultado); 
 })
 .catch(function(error) { 
  console.log('error', error);
  }); 
}

obtenerUsuarios();
</code></pre><p>Como puedes ver, hemos simplificado mucho el código. Entonces, cuando no proporcionamos ningún argumento a la función <code>obtenerUsuarios</code>, esta tomará valores predeterminados. También podemos proporcionar nuestros propios valores de esta forma:</p><pre><code class="language-js">obtenerUsuarios(1, 20, 'female', 'gb');
</code></pre><p>Lo cual sobrescribirá los parámetros predeterminados de la función.</p><h3 id="null-no-es-igual-a-undefined"><strong>null </strong>no es igual a<strong> undefined</strong></h3><p>Pero debes tener en cuenta algo importante: <code>null</code> y <code>undefined</code> son dos cosas diferentes al definir parámetros predeterminados.</p><p>Observa el siguiente código:</p><pre><code class="language-js">function mostrar(nombre = 'David', edad = 35, ubicacion = 'NY'){
 console.log(nombre, edad, ubicacion); 
}

mostrar('David', 35); // David 35 NY
mostrar('David', 35, undefined); // David 35 NY
</code></pre><p>Como no hemos proporcionado el tercer valor para el parámetro de ubicación en la primera llamada a <code>mostrar</code>, este será <code>undefined</code> por defecto, por lo dicho valor <code>undefined</code> se utilizará en ambas llamadas de función. Sin embargo, las siguientes llamadas a funciones <strong>no</strong> son iguales.</p><pre><code class="language-js">display('David', 35, undefined); // David 35 NY
display('David', 35, null); // David 35 null
</code></pre><p>Cuando pasamos <code>null</code> como argumento, estamos diciendo específicamente que asignemos un valor <code>null</code> (nulo) al parámetro de <code>ubicacion</code> lo cual es diferente que <code>undefined</code> (indefinido). Por lo tanto, no tomará el valor predeterminado de <code>NY</code>.</p><h2 id="array-prototype-includes"><strong>Array.prototype.includes</strong></h2><p>ES7 ha agregado una nueva función que verifica si un elemento está presente en el arreglo o no y devuelve un valor booleano <code>true</code> o <code>false</code>.</p><pre><code class="language-js">// Código ES5

const numeros = ["uno", "dos", "tres", "cuatro"];

console.log(numeros.indexOf("uno") &gt; -1); // true 
console.log(numeros.indexOf("cinco") &gt; -1); // false</code></pre><p>El mismo código usando el método Array <code>includes</code> puede escribirse como se muestra a continuación:</p><pre><code class="language-js">// Código ES7

const numeros = ["uno", "dos", "tres", "cuatro"];

console.log(numeros.includes("uno")); // true 
console.log(numeros.includes("cinco")); // false</code></pre><p>Por lo tanto, el uso del método Array <code>includes</code> hace que el código sea corto y fácil de entender.</p><p>El método <code>includes</code> también es útil cuando se comparan diferentes valores.</p><p>Observa el siguiente código:</p><pre><code class="language-js">const dia = "lunes";

if(dia === "lunes" || dia === "martes" || dia === "miercoles") {
  // hacer algo
}</code></pre><p>El código anterior se puede simplificar usando el método <code>includes</code> como se muestra a continuación:</p><pre><code class="language-js">const dia = "lunes";

if(["lunes", "martes", "miercoles"].includes(dia)) {
  // hacer algo
}</code></pre><p>Así que, el método <code>includes</code> es bastante útil cuando se buscan valores en un arreglo.</p><h2 id="puntos-finales"><strong>Puntos finales</strong></h2><p>Hay muchos cambios que se han incorporado a JavaScript a partir de ES6. Y todos los desarrolladores de JavaScript, Angular, React o Vue deberían estar al tanto de ellos.</p><p>Conocerlos te convierte en un mejor desarrollador e incluso puede ayudarte a conseguir un trabajo mejor remunerado. Y si solo estás aprendiendo librerías como React y frameworks como Angular y Vue, seguramente querrás estar familiarizado con estas nuevas funcionalidades.</p><h2 id="aprende-m-s-sobre-las-funcionalidades-de-javascript-moderno"><strong>Aprende más sobre las funcionalidades de JavaScript moderno</strong></h2><p>Puedes aprender todo sobre las últimas funcionalidades agregadas en JavaScript en mi libro <a href="https://modernjavascript.yogeshchavan.dev/">Mastering Modern JavaScript</a>. Es la única guía que necesitas para aprender conceptos modernos de JavaScript.</p><figure class="kg-card kg-image-card"><img src="https://modernjavascript.yogeshchavan.dev/book_cover.jpg" class="kg-image" alt="book_cover" width="512" height="800" loading="lazy"></figure><p>Suscríbete a mi <a href="https://bit.ly/2HwVEA2">boletín semanal</a> para unirte a más de 1000 suscriptores y obtener consejos, trucos y artículos increíbles directamente en tu bandeja de entrada.</p><p>Traducido del artículo de <strong><a href="https://www.freecodecamp.org/news/author/yogesh/"><strong>Yogesh Chavan</strong></a><strong> - </strong><a href="https://www.freecodecamp.org/news/learn-modern-javascript/">Modern JavaScript – Imports, Exports, Let, Const, and Promises in ES6+</a></strong></p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
