From 68162242916447872fac49e5fe0b31aa6949300a Mon Sep 17 00:00:00 2001
From: ckdvk Creemos que estamos creando el sistema para nuestros propios propósitos. Creemos que lo estamos haciendo a nuestra propia imagen... Pero la computadora en realidad no es como nosotros. Es una proyección de una parte muy pequeña de nosotros mismos: esa parte dedicada a la lógica, el orden, la regla y la claridad. Este es un libro sobre cómo instruir a computadoras. Las computadoras son tan comunes como los destornilladores hoy en día, pero son bastante más complejas, y hacer que hagan lo que quieres no siempre es fácil. Este es un libro sobre cómo instruir a las computadoras. Las computadoras son tan comunes como los destornilladores hoy en día, pero son bastante más complejas, y hacer que hagan lo que quieres no siempre es fácil. Si la tarea que tienes para tu computadora es común, bien entendida, como mostrarte tu correo electrónico o actuar como una calculadora, puedes abrir la aplicación correspondiente y ponerte a trabajar. Pero para tareas únicas o abiertas, a menudo no hay una aplicación adecuada. Si la tarea que tienes para tu computadora es algo común y bien conocido como mostrarte tu correo electrónico funcionar a modo de calculadora, puedes abrir la aplicación correspondiente y ponerte a trabajar. Sin embargo, para tareas únicas o abiertas, a menudo no hay una aplicación adecuada. Ahí es donde entra en juego la programación. Programar es el acto de construir un programa—un conjunto de instrucciones precisas que le dicen a una computadora qué hacer. Debido a que las computadoras son bestias tontas y pedantes, programar es fundamentalmente tedioso y frustrante. Ahí es donde entra en juego la programación. Programar es el acto de construir un programa—un conjunto de instrucciones precisas que le dicen a una computadora qué hacer. Dado que las computadoras son criaturas estúpidas y cuadriculadas, programar resulta ser una tarea fundamentalmente tediosa y frustrante. Por suerte, si puedes superar ese hecho—e incluso disfrutar del rigor de pensar en términos que las máquinas tontas pueden manejar—programar puede ser gratificante. Te permite hacer cosas en segundos que te tomarían una eternidad a mano. Es una forma de hacer que tu herramienta informática haga cosas que antes no podía hacer. Además, se convierte en un maravilloso juego de resolución de acertijos y pensamiento abstracto. Por suerte, si eres capaz de afrontar esto —y también quizá si disfrutas del rigor de pensar en términos que una de estas máquinas pueda entender— programar puede ser gratificante. Te permite hacer en segundos cosas que te tomarían una eternidad a mano. Es una forma de hacer que tu herramienta informática haga cosas que antes no podía hacer. Además, se convierte en un maravilloso juego de resolución de puzles y pensamiento abstracto. La mayoría de la programación se realiza con lenguajes de programación. Un lenguaje de programación es un lenguaje artificialmente construido utilizado para instruir a las computadoras. Es interesante que la forma más efectiva que hemos encontrado para comunicarnos con una computadora se base tanto en la forma en que nos comunicamos entre nosotros. Al igual que los idiomas humanos, los lenguajes informáticos permiten combinar palabras y frases de nuevas formas, lo que permite expresar conceptos cada vez más nuevos. La mayoría de la programación se realiza con lenguajes de programación. Un lenguaje de programación es un lenguaje artificialmente construido utilizado para dar instrucciones a las computadoras. Es interesante que la forma más efectiva que hemos encontrado para comunicarnos con una computadora se base tanto en la forma en que nos comunicamos entre nosotros. Al igual que los idiomas humanos, los lenguajes informáticos permiten combinar palabras y frases de nuevas maneras, permitiendo expresar nuevos conceptos que no se habían expresado antes. En un momento dado, las interfaces basadas en lenguaje, como los prompts de BASIC y DOS de los años 1980 y 1990, eran el principal método de interactuar con las computadoras. Para el uso informático rutinario, estas se han reemplazado en gran medida por interfaces visuales, que son más fáciles de aprender pero ofrecen menos libertad. Pero si sabes dónde buscar, los lenguajes todavía están ahí. Uno de ellos, JavaScript, está integrado en cada navegador web moderno—y por lo tanto está disponible en casi todos los dispositivos. En un momento dado, las interfaces basadas en lenguaje, como los prompts de BASIC y DOS de los años 1980 y 1990, eran el principal método de interacción con las computadoras. n el uso del día a día, estas se han reemplazado en gran medida por interfaces visuales, que son más fáciles de aprender, aunque ofrecen menos libertad. No obstante, si sabes dónde mirar, los lenguajes de programación siguen ahí. Uno de ellos, JavaScript, está integrado en cada navegador web moderno —y por tanto está disponible en casi todos los dispositivos. Este libro intentará que te familiarices lo suficiente con este lenguaje para hacer cosas útiles y entretenidas con él. Este libro intentará que te familiarices lo suficiente con este lenguaje como para hacer cosas útiles y entretenidas con él. Además de explicar JavaScript, presentaré los principios básicos de la programación. Resulta que programar es difícil. Las reglas fundamentales son simples y claras, pero los programas construidos sobre estas reglas tienden a volverse lo suficientemente complejos como para introducir sus propias reglas y complejidades. Estás construyendo tu propio laberinto, de alguna manera, y fácilmente puedes perderte en él. Además de explicar JavaScript, presentaré los principios básicos de la programación. Resulta que programar es una tarea difícil. Las reglas fundamentales son simples y claras, pero los programas construidos sobre estas reglas tienden a volverse lo suficientemente complejos como para introducir sus propias reglas y complejidades. De algún modo, estás construyendo tu propio laberinto, y es fácil que te pierdas en él. Habrá momentos en los que leer este libro resulte terriblemente frustrante. Si eres nuevo en la programación, habrá mucho material nuevo que asimilar. Gran parte de este material luego se combinará de maneras que requieren que hagas conexiones adicionales. Habrá momentos en los que leer este libro resulte terriblemente frustrante. Si eres nuevo en la programación, habrá mucho material nuevo que asimilar. Gran parte de este material luego se combinará de maneras que requierirán que hagas nuevas conexiones mentales. Depende de ti hacer el esfuerzo necesario. Cuando te cueste seguir el libro, no saques conclusiones precipitadas sobre tus propias capacidades. Estás bien, simplemente necesitas seguir adelante. Tómate un descanso, vuelve a leer algo de material y asegúrate de leer y comprender los programas de ejemplo y los ejercicios. Aprender es un trabajo duro, pero todo lo que aprendas será tuyo y facilitará aún más el aprendizaje futuro. Depende de ti hacer el esfuerzo necesario. Cuando te cueste seguir el libro, no saques conclusiones precipitadas sobre tus propias capacidades. Está todo bien —simplemente necesitas seguir adelante. Tómate un descanso, vuelve a leer algo de material y asegúrate de leer y comprender los programas de ejemplo y los ejercicios. Aprender es un trabajo duro, pero todo lo que aprendas será tuyo y facilitará aún más el aprendizaje futuro. Un programa es muchas cosas. Es un trozo de texto escrito por un programador, es la fuerza directiva que hace que la computadora haga lo que hace, es información en la memoria de la computadora, y al mismo tiempo controla las acciones realizadas en esta memoria. Las analogías que intentan comparar los programas con objetos familiares tienden a quedarse cortas. Una comparación vagamente adecuada es comparar un programa con una máquina: suelen estar implicadas muchas partes separadas y, para hacer que todo funcione, debemos considerar las formas en que estas partes se interconectan y contribuyen a la operación del conjunto. Un programa es muchas cosas. Es un trozo de texto escrito por un programador, es la fuerza directriz que hace que la computadora haga lo que hace, es información en la memoria de la computadora, y al mismo tiempo controla las acciones realizadas en esta memoria. Las analogías que intentan comparar los programas con objetos familiares tienden a quedarse cortas. Una comparación vagamente adecuada es comparar un programa con una máquina: suelen estar formadas por muchas partes separadas y, para hacer que todo funcione, debemos considerar las formas en que estas partes se interconectan y contribuyen a la operación del conjunto. Una computadora es una máquina física que actúa como anfitriona de estas máquinas inmateriales. Las computadoras mismas solo pueden hacer cosas increíblemente sencillas. La razón por la que son tan útiles es que hacen estas cosas a una velocidad increíblemente alta. Un programa puede combinar ingeniosamente un número enorme de estas acciones simples para hacer cosas muy complicadas. Una computadora es una máquina física que actúa como anfitriona de estas máquinas inmateriales. Una computadora por si sola solo es capaz de hacer cosas estúpidamente sencillas. La razón por la que son tan útiles es que hacen estas cosas a una velocidad increíblemente alta. Un programa puede combinar ingeniosamente un número enorme de estas acciones simples para hacer cosas muy complicadas. Un programa es una construcción del pensamiento. Es gratuito de construir, es liviano y crece fácilmente bajo nuestras manos al teclear. Pero a medida que un programa crece, también lo hace su complejidad. La habilidad de programar es la habilidad de construir programas que no te confundan a ti mismo. Los mejores programas son aquellos que logran hacer algo interesante mientras siguen siendo fáciles de entender. Un programa es una construcción del pensamiento. No tiene coste ni peso, y crece fácilmente según tecleamos. Pero a medida que un programa crece, también lo hace su complejidad. La habilidad de programar es la habilidad de construir programas que no te confundan a ti mismo. Los mejores programas son aquellos que logran hacer algo interesante mientras siguen siendo fáciles de entender. Algunos programadores creen que esta complejidad se gestiona mejor utilizando solo un conjunto pequeño de técnicas bien comprendidas en sus programas. Han compuesto reglas estrictas (“mejores prácticas”) que prescriben la forma que deberían tener los programas y se mantienen cuidadosamente dentro de su pequeña zona segura. Algunos programadores creen que esta complejidad se gestiona mejor utilizando solo un puñado de técnicas conocidas en sus programas. Han creado reglas estrictas (“mejores prácticas”) que prescriben la forma que deberían tener los programas y se mantienen diligentemente dentro de su pequeño espacio seguro. Esto no solo es aburrido, es inefectivo. A menudo, nuevos problemas requieren soluciones nuevas. El campo de la programación es joven y aún se está desarrollando rápidamente, y es lo suficientemente variado como para tener espacio para enfoques radicalmente diferentes. Hay muchos errores terribles que cometer en el diseño de programas, y deberías ir y cometerlos al menos una vez para entenderlos. Una noción de cómo es un buen programa se desarrolla con la práctica, no se aprende de una lista de reglas. Esto no solo es aburrido sino que es ineficaz. A menudo, nuevos problemas requieren soluciones nuevas. El campo de la programación es joven y sin embargo se está desarrollando rápidamente, con variedad suficiente como para adoptar enfoques radicalmente distintos. Hay muchos errores terribles que cometer en el diseño de un programa, y deberías cometerlos al menos una vez para entenderlos. Una noción de cómo es un buen programa se desarrolla con la práctica, no se aprende de una lista de reglas. Al principio, en los inicios de la informática, no existían los lenguajes de programación. Los programas lucían algo así: Al principio, en los inicios de la informática, no existían los lenguajes de programación. Los programas tenían una pinta como la siguiente: Este es un programa para sumar los números del 1 al 10 y mostrar el resultado: Este es un programa para sumar los números del 1 al 10 y mostrar el resultado: Por supuesto, introducir manualmente estos patrones arcanos de bits (los unos y ceros) hacía que el programador se sintiera como un mago poderoso. Y eso debe valer algo en términos de satisfacción laboral. Por supuesto, introducir manualmente estos misteriosos patrones de bits (los unos y ceros) hacía que el programador se sintiera como un mago poderoso. Y eso debe valer algo en términos de satisfacción laboral. Cada línea del programa anterior contiene una única instrucción. Podría escribirse en español de la siguiente manera: Aunque eso ya es más legible que la sopa de bits, sigue siendo bastante confusa. Usar nombres en lugar de números para las instrucciones y las ubicaciones de memoria ayuda: Aunque eso ya es más legible que la sopa de bits anterior, sigue siendo bastante confuso. Usar nombres en lugar de números para las instrucciones y las ubicaciones de memoria ayuda: ¿Puedes ver cómo funciona el programa en este punto? Las dos primeras líneas asignan los valores iniciales a dos ubicaciones de memoria: ¿Puedes ver cómo funciona el programa en este punto? Las dos primeras líneas asignan los valores iniciales a dos ubicaciones de memoria: Esta versión nos proporciona algunas mejoras. Lo más importante es que ya no es necesario especificar la forma en que queremos que el programa salte hacia adelante y hacia atrás; la construcción Esta versión nos proporciona algunas mejoras más. Lo más importante es que ya no es necesario especificar la forma en que queremos que el programa salte hacia adelante y hacia atrás; la construcción Al final del programa, después de que la construcción Al final del programa, después de que la construcción Finalmente, así es como podría verse el programa si tuviéramos a nuestra disposición las operaciones convenientes Finalmente, así es como podría verse el programa si tuviéramos a nuestra disposición las útiles operaciones La moraleja de esta historia es que el mismo programa puede expresarse de formas largas y cortas, ilegibles y legibles. La primera versión del programa era extremadamente críptica, mientras que esta última es casi en inglés: registra ( La moraleja de esta historia es que un mismo programa puede expresarse de formas largas y cortas, ilegibles y legibles. La primera versión del programa era extremadamente críptica, mientras que esta última es casi hablar en inglés: registra ( Un buen lenguaje de programación ayuda al programador al permitirle hablar sobre las acciones que la computadora debe realizar a un nivel más alto. Ayuda a omitir detalles, proporciona bloques de construcción convenientes (como Un buen lenguaje de programación ayuda al programador, al permitirle hablar sobre las acciones que la computadora debe realizar a un más alto nivel. Ayuda a omitir detalles, proporciona bloques de construcción convenientes (como JavaScript fue introducido en 1995 como una forma de agregar programas a páginas web en el navegador Netscape Navigator. Desde entonces, el lenguaje ha sido adoptado por todos los demás navegadores web gráficos principales. Ha hecho posibles aplicaciones web modernas, es decir, aplicaciones con las que puedes interactuar directamente sin tener que recargar la página para cada acción. JavaScript también se utiliza en sitios web más tradicionales para proporcionar distintas formas de interactividad e ingenio. JavaScript fue introducido en 1995 como una forma de agregar programas a páginas web en el navegador Netscape Navigator. Desde entonces, el lenguaje ha sido adoptado por todos los demás principales navegadores web gráficos. Ha hecho posibles aplicaciones web modernas, es decir, aplicaciones con las que puedes interactuar directamente sin tener que recargar la página para cada acción. JavaScript también se utiliza en sitios web más tradicionales para proporcionar distintas formas de interactividad e ingenio. Es importante tener en cuenta que JavaScript casi no tiene nada que ver con el lenguaje de programación llamado Java. El nombre similar fue inspirado por consideraciones de marketing en lugar de un buen juicio. Cuando se estaba introduciendo JavaScript, el lenguaje Java se estaba comercializando mucho y ganaba popularidad. Alguien pensó que era una buena idea intentar aprovechar este éxito. Ahora estamos atrapados con el nombre. Es importante mencionar que JavaScript no tiene casi nada que ver con el lenguaje de programación llamado Java. La elección de un nombre tan parecido se debe más a consideraciones de marketing que a un buen criterio. Cuando se estaba introduciendo JavaScript, el lenguaje Java se estaba comercializando mucho y ganaba popularidad. Alguien pensó que era una buena idea intentar aprovechar este éxito y ahora tenemos que quedarnos con el nombre. Después de su adopción fuera de Netscape, se escribió un documento estándar para describir la forma en que debería funcionar el lenguaje JavaScript para que las diversas piezas de software que afirmaban soportar JavaScript pudieran asegurarse de que realmente proporcionaban el mismo lenguaje. Esto se llama el estándar ECMAScript, según la organización Ecma International que llevó a cabo la estandarización. En la práctica, los términos ECMAScript y JavaScript se pueden usar indistintamente, son dos nombres para el mismo lenguaje. Después de su adopción fuera de Netscape, se redactó un documento estándar para describir cómo debería funcionar el lenguaje JavaScript, de manera que los diferentes programas que decían soportar JavaScript pudieran asegurarse de que realmente proporcionaban el mismo lenguaje. A esto se le llama el estándar ECMAScript, en honor a la organización Ecma International que llevó a cabo la estandarización. En la práctica, los términos ECMAScript y JavaScript se pueden usar de manera intercambiable; son dos nombres para el mismo lenguaje. Hay quienes dirán cosas terribles sobre JavaScript. Muchas de esas cosas son ciertas. Cuando me pidieron que escribiera algo en JavaScript por primera vez, rápidamente llegué a detestarlo. Aceptaba casi cualquier cosa que escribía pero lo interpretaba de una manera completamente diferente a lo que yo quería decir. Esto tenía mucho que ver con el hecho de que no tenía ni idea de lo que estaba haciendo, por supuesto, pero hay un problema real aquí: JavaScript es ridículamente liberal en lo que permite. La idea detrás de este diseño era que haría la programación en JavaScript más fácil para principiantes. En realidad, esto hace que encontrar problemas en tus programas sea más difícil porque el sistema no te los señalará. Hay quienes dirán cosas terribles sobre JavaScript. Muchas de ellas son ciertas. Cuando me pidieron que escribiera algo en JavaScript por primera vez, empecé a detestarlo rápidamente. Aceptaba casi cualquier cosa que escribía pero lo interpretaba de una manera completamente diferente a lo que yo quería decir. Esto tenía mucho que ver con el hecho de que yo no tenía ni idea de lo que estaba haciendo, por supuesto, pero hay un problema real aquí: JavaScript es ridículamente flexible en lo que permite. La idea detrás de este diseño era que haría la programación en JavaScript más fácil para principiantes. En realidad, esto hace que encontrar problemas en tus programas sea más difícil porque el sistema no te los va a señalar. Esta flexibilidad también tiene sus ventajas. Deja espacio para técnicas imposibles en lenguajes más rígidos y permite un estilo de programación agradable e informal. Después de aprender el lenguaje adecuadamente y trabajar con él durante un tiempo, ha llegado a realmente gustarme JavaScript. Ha habido varias versiones de JavaScript. La versión ECMAScript 3 fue la versión ampliamente soportada durante el ascenso al dominio de JavaScript, aproximadamente entre 2000 y 2010. Durante este tiempo, se estaba trabajando en una versión ambiciosa 4, la cual planeaba una serie de mejoras y extensiones radicales al lenguaje. Cambiar un lenguaje vivo y ampliamente utilizado de esa manera resultó ser políticamente difícil, y el trabajo en la versión 4 fue abandonado en 2008. Una versión 5, mucho menos ambiciosa, que solo realizaba algunas mejoras no controversiales, salió en 2009. En 2015, salió la versión 6, una actualización importante que incluía algunas de las ideas previstas para la versión 4. Desde entonces, hemos tenido nuevas actualizaciones pequeñas cada año. Ha habido varias versiones de JavaScript. La versión ECMAScript 3 fue la versión más respaldada durante el ascenso al dominio de JavaScript, aproximadamente entre 2000 y 2010. Durante este tiempo, se estaba trabajando en una ambiciosa versión 4, la cual planeaba una serie de mejoras y extensiones radicales del lenguaje. Cambiar un lenguaje vivo y ampliamente utilizado de esa manera resultó ser políticamente difícil, y el trabajo en la versión 4 se abandonó en 2008. Una mucho menos ambiciosa versión 5, que solo realizaba algunas mejoras poco controvertidas, se lanzó en 2009. En 2015, salió la versión 6, una actualización importante que incluía algunas de las ideas previstas para la versión 4. Desde entonces, hemos tenido nuevas pequeñas actualizaciones cada año. El hecho de que JavaScript esté evolucionando significa que los navegadores tienen que mantenerse constantemente al día. Si estás usando un navegador más antiguo, es posible que no admita todas las funciones. Los diseñadores del lenguaje se aseguran de no realizar cambios que puedan romper programas existentes, por lo que los nuevos navegadores aún pueden ejecutar programas antiguos. En este libro, estoy utilizando la versión 2023 de JavaScript. El hecho de que JavaScript esté evolucionando significa que los navegadores tienen que mantenerse constantemente al día. Si estás usando un navegador más antiguo, es posible que no admita todas las funciones. Los diseñadores del lenguaje se aseguran de no realizar cambios que puedan romper programas ya existentes, por lo que los nuevos navegadores aún pueden ejecutar programas antiguos. En este libro, estoy utilizando la versión 2023 de JavaScript. Los navegadores web no son las únicas plataformas en las que se utiliza JavaScript. Algunas bases de datos, como MongoDB y CouchDB, utilizan JavaScript como su lenguaje de secuencias de comandos y consulta. Varias plataformas para programación de escritorio y servidores, especialmente el proyecto Node.js (el tema del Capítulo 20), proporcionan un entorno para programar en JavaScript fuera del navegador. El código es el texto que constituye los programas. La mayoría de los capítulos en este libro contienen bastante código. Creo que leer código y escribir código son partes indispensables de aprender a programar. Intenta no solo echar un vistazo a los ejemplos, léelos atentamente y entiéndelos. Esto puede ser lento y confuso al principio, pero te prometo que pronto le tomarás la mano. Lo mismo ocurre con los ejercicios. No des por sentado que los entiendes hasta que hayas escrito realmente una solución que funcione. El código es el texto que constituye los programas. La mayoría de los capítulos en este libro contienen bastante código. Creo que leer código y escribir código son partes indispensables de aprender a programar. Intenta no solo mirar por encima los ejemplos, léelos atentamente y entiéndelos. Esto puede ser lento y confuso al principio, pero te prometo que pronto le pillarás el truco. Lo mismo ocurre con los ejercicios. No des por sentado que los entiendes hasta que hayas escrito una solución que realmente funcione. Te recomiendo que pruebes tus soluciones a los ejercicios en un intérprete de JavaScript real. De esta manera, obtendrás comentarios inmediatos sobre si lo que estás haciendo funciona, y, espero, te tentarán a experimentar y a ir más allá de los ejercicios. Cuando leas este libro en tu navegador, puedes editar (y ejecutar) todos los programas de ejemplo haciendo clic en ellos. Ejecutar los programas definidos en este libro fuera del sitio web del libro requiere cierto cuidado. Muchos ejemplos son independientes y deberían funcionar en cualquier entorno de JavaScript. Pero el código en los capítulos posteriores a menudo está escrito para un entorno específico (navegador o Node.js) y solo puede ejecutarse allí. Además, muchos capítulos definen programas más grandes, y las piezas de código que aparecen en ellos dependen unas de otras o de archivos externos. El sandbox en el sitio web proporciona enlaces a archivos ZIP que contienen todos los scripts y archivos de datos necesarios para ejecutar el código de un capítulo dado. Ejecutar los programas definidos en este libro fuera del sitio web del libro requiere cierto cuidado. Muchos ejemplos son independientes y deberían funcionar en cualquier entorno de JavaScript. Pero el código en los capítulos posteriores a menudo está escrito para un entorno específico (navegador o Node.js) y solo puede ejecutarse allí. Además, muchos capítulos definen programas más grandes, y los trozos de código que aparecen en ellos dependen unos de otros, o de archivos externos. El sandbox en el sitio web proporciona enlaces a archivos ZIP que contienen todos los scripts y archivos de datos necesarios para ejecutar el código de un capítulo dado. Este libro consta aproximadamente de tres partes. Los primeros 12 capítulos tratan sobre el lenguaje JavaScript. Los siguientes siete capítulos son acerca de los navegadores web y la forma en que se utiliza JavaScript para programarlos. Por último, dos capítulos están dedicados a Node.js, otro entorno para programar en JavaScript. Hay cinco capítulos de proyectos en el libro que describen programas de ejemplo más grandes para darte una idea de la programación real. Este libro consta aproximadamente de tres partes. Los primeros 12 capítulos tratan sobre el lenguaje JavaScript. Los siguientes siete capítulos son acerca de los navegadores web y la forma en que se utiliza JavaScript para programarlos. Por último, se dedican dos capítulos a Node.js, otro entorno para programar en JavaScript. Hay cinco capítulos de proyectos en el libro que describen programas de ejemplo más grandes para darte una idea de programación de verdad. La parte del lenguaje del libro comienza con cuatro capítulos que introducen la estructura básica del lenguaje JavaScript. Discuten las estructuras de control (como la palabra La parte del libro sobre el lenguaje comienza con cuatro capítulos que introducen la estructura básica del lenguaje JavaScript. En ellos, se discuten las estructuras de control (como la palabra La segunda parte del libro, de los capítulos 13 a 19, describe las herramientas a las que tiene acceso JavaScript en un navegador. Aprenderás a mostrar cosas en la pantalla (Capítulos 14 y 17), responder a la entrada del usuario (Capítulo 15) y comunicarte a través de la red (Capítulo 18). Nuevamente hay dos capítulos de proyecto en esta parte, construyendo un juego de plataformas y un programa de pintura de píxeles. Después de un primer capítulo de proyecto en el que se construye un robot de entrega rudimentario, la parte del libro sobre lenguaje continúa con capítulos acerca de manejo de errores y corrección de errores, expresiones regulares (una herramienta importante para trabajar con texto), modularidad (otra defensa contra la complejidad) y programación asíncrona (tratando con eventos que llevan tiempo). El segundo capítulo de proyecto, donde implementamos un lenguaje de programación, cierra la primera parte del libro. El Capítulo 20 describe Node.js, y el Capítulo 21 construye un pequeño sitio web utilizando esa herramienta. La segunda parte del libro, de los capítulos 13 a 19, describe las herramientas a las que tiene acceso JavaScript en un navegador. Aprenderás a mostrar cosas en la pantalla (Capítulos 14 y 17), responder a la entrada del usuario (Capítulo 15) y comunicarte a través de la red (Capítulo 18). Nuevamente hay dos capítulos de proyecto en esta parte que consisten construir un juego de plataformas y un programa de pintura de píxeles, respectivamente. En el Capítulo 20 se describe Node.js, y en el Capítulo 21 se construye un pequeño sitio web utilizando esta herramienta. En este libro, el texto escrito en una fuente En este libro, el texto escrito en una fuente A veces, para mostrar la salida que produce un programa, la salida esperada se escribe después, con dos barras inclinadas y una flecha al frente. A veces, para mostrar la salida que produce un programa, la salida esperada se escribe después, con dos barras diagonales y una flecha en frente. En el mundo de la computadora, solo existe data. Puedes leer data, modificar data, crear nueva data, pero aquello que no es data no puede ser mencionado. Toda esta data se almacena como largas secuencias de bits y, por lo tanto, es fundamentalmente similar. En el mundo de la computadora, solo existen datos. Puedes leer datos, modificar datos, crear nuevos datos, pero aquello que no son datos no puede ser mencionado. Todos estos datos se almacenan como largas secuencias de bits y, por lo tanto, es fundamentalmente similar. Los bits son cualquier tipo de cosas de dos valores, generalmente descritos como ceros y unos. Dentro de la computadora, toman formas como una carga eléctrica alta o baja, una señal fuerte o débil, o un punto brillante u opaco en la superficie de un CD. Cualquier pieza de información discreta puede reducirse a una secuencia de ceros y unos y por lo tanto representarse en bits.Introducción

Sobre la programación
-
@@ -48,19 +48,19 @@
-
Por qué importa el lenguaje
-00110001 00000000 00000000
00110001 00000001 00000001
@@ -72,9 +72,9 @@
-
1 + 2 + .. Podría ejecutarse en una máquina hipotética simple. Para programar los primeros ordenadores, era necesario configurar grandes conjuntos de interruptores en la posición correcta o perforar agujeros en tiras de cartón y alimentarlos al ordenador. Puedes imaginar lo tedioso y propenso a errores que era este procedimiento. Incluso escribir programas simples requería mucha astucia y disciplina. Los complejos eran casi inconcebibles.1 + 2 + .. Podría ejecutarse en una máquina hipotética simple. Para programar los primeros ordenadores, era necesario configurar grandes conjuntos de interruptores en la posición correcta o perforar agujeros en tiras de cartón y dárselos a la computadora. Ya te puedes imaginar lo tedioso y propenso a errores que era este procedimiento. Incluso escribir programas simples requería de mucha astucia y disciplina. Los complejos eran casi inconcebibles.
-
Establecer “total” en 0.
Establecer “count” en 1.
@@ -132,7 +132,7 @@
-
total se utilizará para construir el resultado de la computación, y count llevará la cuenta del número que estamos observando en ese momento. Las líneas que utilizan compare probablemente sean las más confusas. El programa quiere ver si count es igual a 11 para decidir si puede dejar de ejecutarse. Debido a que nuestra máquina hipotética es bastante primitiva, solo puede comprobar si un número es cero y tomar una decisión en función de ese valor. Por lo tanto, utiliza la ubicación de memoria etiquetada como compare para calcular el valor de count - 11 y tomar una decisión basada en ese valor. Las siguientes dos líneas suman el valor de count al resultado e incrementan count en 1 cada vez que el programa decide que count aún no es 11. Aquí está el mismo programa en JavaScript:total se utilizará para construir el resultado de la suma, y count llevará la cuenta del número que estamos observando en ese momento. Las líneas que utilizan compare probablemente sean las más confusas. El programa quiere ver si count es igual a 11 para decidir si puede parar de ejecutarse. Debido a que nuestra máquina hipotética es bastante primitiva, solo puede comprobar si un número es cero y tomar una decisión en función de ese valor. Por lo tanto, utiliza la ubicación de memoria etiquetada como compare para calcular el valor de count - 11 y tomar una decisión basada en el resultado. Las siguientes dos líneas suman el valor de count al resultado e incrementan count en 1 cada vez que el programa decide que count aún no vale 11. Aquí está el mismo programa en JavaScript:let total = 0, count = 1;
while (count <= 10) {
@@ -142,60 +142,62 @@
-// → 55
while se encarga de eso. Continúa ejecutando el bloque (entre llaves) debajo de él siempre y cuando se cumpla la condición que se le ha dado. Esa condición es count <= 10, lo que significa “el recuento es menor o igual a 10”. Ya no tenemos que crear un valor temporal y compararlo con cero, lo cual era simplemente un detalle no interesante. Parte del poder de los lenguajes de programación es que pueden encargarse de los detalles no interesantes por nosotros.while se encarga de eso. Continúa ejecutando el bloque (entre llaves) debajo de él siempre y cuando se cumpla la condición que se le ha dado. Esa condición es count <= 10, lo que significa “el recuento es menor o igual a 10”. Ya no tenemos que crear un valor temporal y compararlo con cero, lo cual era simplemente un detalle carente de interés. Parte del poder de los lenguajes de programación es que pueden encargarse de los detalles que no nos interesan.while haya terminado, se utiliza la operación console.log para escribir el resultado.while haya terminado, se utiliza la operación console.log para mostrar el resultado.rango y suma, que respectivamente crean una colección de números dentro de un rango y calculan la suma de una colección de números:rango y suma, que crean una colección de números dentro de un rango y calculan la suma de una colección de números, respectivamente:console.log(suma(rango(1, 10)));
// → 55
-log) la suma del rango de números del 1 al 10. (Veremos en capítulos posteriores cómo definir operaciones como suma y rango.)log) la suma del rango de números del 1 al 10 (veremos en capítulos posteriores cómo definir operaciones como suma y rango).while y console.log), te permite definir tus propios bloques de construcción (como suma y rango), y hace que esos bloques sean fáciles de componer.while y console.log), te permite definir tus propios bloques de construcción (como suma y rango), y hace que esos bloques sean fáciles de componer.¿Qué es JavaScript?
-Código y qué hacer con él
+Código, y qué hacer con él
-Visión general de este libro
-while que viste en esta introducción), las funciones (escribir tus propios bloques de construcción) y las estructuras de datos. Después de estos, serás capaz de escribir programas básicos. Luego, los Capítulos 5 y 6 introducen técnicas para usar funciones y objetos para escribir código más abstracto y mantener la complejidad bajo control. Después de un primer capítulo del proyecto que construye un robot de entrega rudimentario, la parte del lenguaje del libro continúa con capítulos sobre manejo de errores y corrección de errores, expresiones regulares (una herramienta importante para trabajar con texto), modularidad (otra defensa contra la complejidad) y programación asíncrona (tratando con eventos que toman tiempo). El segundo capítulo del proyecto, donde implementamos un lenguaje de programación, concluye la primera parte del libro.while que viste en esta introducción), las funciones (escribir tus propios bloques de construcción) y las estructuras de datos. Después de estos, serás capaz de escribir programas básicos. Luego, los Capítulos 5 y 6 introducen técnicas para usar funciones y objetos para escribir código más abstracto y mantener la complejidad bajo control.Convenciones tipográficas
-monoespaciada representará elementos de programas. A veces estos son fragmentos autosuficientes, y a veces simplemente se refieren a partes de un programa cercano. Los programas (de los cuales ya has visto algunos) se escriben de la siguiente manera:monoespaciada representará partes de programas. A veces serán fragmentos autosuficientes, y a veces simplemente se referirán a partes de un programa que se acabe de comentar. Los programas (de los cuales ya has visto algunos) se escriben de la siguiente manera:function factorial(n) {
if (n == 0) {
@@ -205,7 +207,7 @@
-
console.log(factorial(8));
// → 40320
diff --git a/html/01_values.html b/html/01_values.html
index 56c1e7db..a7b182d1 100644
--- a/html/01_values.html
+++ b/html/01_values.html
@@ -20,7 +20,7 @@ Valores, Tipos y Operadores

La memoria de la computadora solía ser mucho más pequeña, y la gente solía utilizar grupos de 8 o 16 bits para representar sus números. Era fácil tener un desbordamiento accidental con números tan pequeños, terminando con un número que no encajaba en la cantidad dada de bits. Hoy en día, incluso las computadoras que caben en tu bolsillo tienen mucha memoria, por lo que puedes utilizar trozos de 64 bits y solo necesitas preocuparte por el desbordamiento cuando lidias con números realmente astronómicos.
Sin embargo, no todos los números enteros menores que 18 mil trillones encajan en un número de JavaScript. Esos bits también almacenan números negativos, por lo que un bit indica el signo del número. Un problema más grande es representar números no enteros. Para hacer esto, algunos de los bits se utilizan para almacenar la posición del punto decimal. El número entero máximo real que se puede almacenar está más en el rango de 9 cuatrillones (15 ceros), que sigue siendo increíblemente grande.
+Sin embargo, no todos los números enteros menores que 18 mil trillones encajan en un número de JavaScript. Esos bits también almacenan números negativos, por lo que un bit indica el signo del número. Un problema más grande es representar números no enteros. Para hacer esto, algunos de los bits se utilizan para almacenar la posición del punto decimal. El número entero máximo real que se puede almacenar está más en el rango de 9 mil billones (15 ceros), que sigue siendo increíblemente grande.
Los números fraccionarios se escriben usando un punto:
@@ -63,7 +63,7 @@Los cálculos con números enteros (también llamados enteros) que son más pequeños que los mencionados 9 cuatrillones siempre serán precisos. Desafortunadamente, los cálculos con números fraccionarios generalmente no lo son. Así como π (pi) no puede expresarse con precisión mediante un número finito de dígitos decimales, muchos números pierden algo de precisión cuando solo están disponibles 64 bits para almacenarlos. Es una lástima, pero solo causa problemas prácticos en situaciones específicas. Lo importante es ser consciente de esto y tratar los números digitales fraccionarios como aproximaciones, no como valores precisos.
+Se garantiza que los cálculos con números enteros (también llamados enteros) menores que los 9 mil billones antes mencionados siempre serán precisos. Desafortunadamente, los cálculos con números fraccionarios generalmente no lo son. Así como π (pi) no puede expresarse con precisión mediante un número finito de dígitos decimales, muchos números pierden algo de precisión cuando solo están disponibles 64 bits para almacenarlos. Es una lástima, pero solo causa problemas prácticos en situaciones específicas. Lo importante es ser consciente de esto y tratar los números digitales fraccionarios como aproximaciones, no como valores precisos.
+ y * se llaman operadores. El primero representa la suma y el segundo representa la multiplicación. Colocar un operador entre dos valores aplicará ese operador a esos valores y producirá un nuevo valor.
-¿Significa este ejemplo “Sumar 4 y 100, y luego multiplicar el resultado por 11”, o se realiza primero la multiplicación antes de la suma? Como habrás adivinado, la multiplicación se realiza primero. Como en matemáticas, puedes cambiar esto envolviendo la suma entre paréntesis:
+¿Significa este ejemplo “Sumar 4 y 100, y luego multiplicar el resultado por 11”, o se realiza primero la multiplicación antes de la suma? Como habrás adivinado, la multiplicación se realiza primero. Pero igual que en matemáticas, puedes cambiar esto envolviendo la suma entre paréntesis:
(100 + 4) * 11@@ -89,7 +89,7 @@
Infinity y -Infinity, que representan el infinito positivo y negativo. Infinity - 1 sigue siendo Infinity, y así sucesivamente. Sin embargo, no confíes demasiado en los cálculos basados en infinito. No es matemáticamente sólido y rápidamente te llevará al siguiente número especial: NaN.
-NaN significa “no es un número”, aunque es un valor del tipo numérico. Obtendrás este resultado cuando, por ejemplo, intentes calcular 0 / 0 (cero dividido por cero), Infinity - Infinity, u cualquier otra operación numérica que no produzca un resultado significativo.
NaN significa “no es un número”, aunque es un valor del tipo numérico. Obtendrás este resultado cuando, por ejemplo, intentes calcular 0 / 0 (cero dividido por cero), Infinity - Infinity, o cualquier otra operación numérica que no produzca un resultado significativo.
Sin embargo, hay una complicación: la representación de JavaScript utiliza 16 bits por elemento de cadena, lo que puede describir hasta 216 caracteres diferentes. Sin embargo, Unicode define más caracteres que eso —aproximadamente el doble, en este momento. Por lo tanto, algunos caracteres, como muchos emoji, ocupan dos “posiciones de caracteres” en las cadenas de JavaScript. Volveremos a esto en el Capítulo 5.
+Pero hay una complicación: la representación de JavaScript utiliza 16 bits por elemento de cadena, lo que puede describir hasta 216 caracteres diferentes. Sin embargo, Unicode define más caracteres que eso (aproximadamente el doble), en este momento. Por lo tanto, algunos caracteres, como muchos emoji, ocupan dos “posiciones de caracteres” en las cadenas de JavaScript. Volveremos a esto en el Capítulo 5.
-Las cadenas no se pueden dividir, multiplicar o restar. El operador + se puede usar en ellas, no para sumar, sino para concatenar —unir dos cadenas. La siguiente línea producirá la cadena "concatenar":
Las cadenas no se pueden dividir, multiplicar o restar. El operador + se puede usar en ellas, no para sumar, sino para concatenar (unir dos cadenas). La siguiente línea producirá la cadena "concatenar":
"con" + "cat" + "e" + "nar"diff --git a/html/ejs.js b/html/ejs.js index 15aea209..9e9f6a72 100644 --- a/html/ejs.js +++ b/html/ejs.js @@ -1 +1 @@ -!function(t){"function"==typeof define&&define.amd?define(t):t()}((function(){"use strict";class t{lineAt(t){if(t<0||t>this.length)throw new RangeError(`Invalid position ${t} in document of length ${this.length}`);return this.lineInner(t,!1,1,0)}line(t){if(t<1||t>this.lines)throw new RangeError(`Invalid line number ${t} in ${this.lines}-line document`);return this.lineInner(t,!0,1,0)}replace(t,e,n){[t,e]=h(this,t,e);let r=[];return this.decompose(0,t,r,2),n.length&&n.decompose(0,n.length,r,3),this.decompose(e,this.length,r,1),i.from(r,this.length-(e-t)+n.length)}append(t){return this.replace(this.length,this.length,t)}slice(t,e=this.length){[t,e]=h(this,t,e);let n=[];return this.decompose(t,e,n,0),i.from(n,e-t)}eq(t){if(t==this)return!0;if(t.length!=this.length||t.lines!=this.lines)return!1;let e=this.scanIdentical(t,1),i=this.length-this.scanIdentical(t,-1),n=new s(this),r=new s(t);for(let t=e,s=e;;){if(n.next(t),r.next(t),t=0,n.lineBreak!=r.lineBreak||n.done!=r.done||n.value!=r.value)return!1;if(s+=n.value.length,n.done||s>=i)return!0}}iter(t=1){return new s(this,t)}iterRange(t,e=this.length){return new o(this,t,e)}iterLines(t,e){let i;if(null==t)i=this.iter();else{null==e&&(e=this.lines+1);let n=this.line(t).from;i=this.iterRange(n,Math.max(n,e==this.lines+1?this.length:e<=1?0:this.line(e-1).to))}return new a(i)}toString(){return this.sliceString(0)}toJSON(){let t=[];return this.flatten(t),t}constructor(){}static of(n){if(0==n.length)throw new RangeError("A document must have at least one line");return 1!=n.length||n[0]?n.length<=32?new e(n):i.from(e.split(n,[])):t.empty}}class e extends t{constructor(t,e=function(t){let e=-1;for(let i of t)e+=i.length+1;return e}(t)){super(),this.text=t,this.length=e}get lines(){return this.text.length}get children(){return null}lineInner(t,e,i,n){for(let r=0;;r++){let s=this.text[r],o=n+s.length;if((e?i:o)>=t)return new l(n,o,i,s);n=o+1,i++}}decompose(t,i,s,o){let a=t<=0&&i>=this.length?this:new e(r(this.text,t,i),Math.min(i,this.length)-Math.max(0,t));if(1&o){let t=s.pop(),i=n(a.text,t.text.slice(),0,a.length);if(i.length<=32)s.push(new e(i,t.length+a.length));else{let t=i.length>>1;s.push(new e(i.slice(0,t)),new e(i.slice(t)))}}else s.push(a)}replace(t,s,o){if(!(o instanceof e))return super.replace(t,s,o);[t,s]=h(this,t,s);let a=n(this.text,n(o.text,r(this.text,0,t)),s),l=this.length+o.length-(s-t);return a.length<=32?new e(a,l):i.from(e.split(a,[]),l)}sliceString(t,e=this.length,i="\n"){[t,e]=h(this,t,e);let n="";for(let r=0,s=0;r<=e&&s
u){let t=oi.build(this.view.state.doc,u,i.range.fromB,this.decorations,this.dynamicDecorationMap),e=oi.build(this.view.state.doc,i.range.toB,p,this.decorations,this.dynamicDecorationMap);o=t.breakAtStart,a=t.openStart,l=e.openEnd;let n=this.compositionView(i);e.breakAtStart?n.breakAfter=1:e.content.length&&n.merge(n.length,n.length,e.content[0],!1,e.openStart,0)&&(n.breakAfter=e.content[0].breakAfter,e.content.shift()),t.content.length&&n.merge(0,0,t.content[t.content.length-1],!0,0,t.openEnd)&&t.content.pop(),s=t.content.concat(n).concat(e.content)}else({content:s,breakAtStart:o,openStart:a,openEnd:l}=oi.build(this.view.state.doc,u,p,this.decorations,this.dynamicDecorationMap));let{i:d,off:f}=r.findPos(c,1),{i:O,off:m}=r.findPos(h,-1);ke(this,O,m,d,f,s,o,a,l)}i&&this.fixCompositionDOM(i)}compositionView(t){let e=new We(t.text.nodeValue);e.flags|=8;for(let{deco:i}of t.marks)e=new qe(i,[e],e.length);let i=new Fe;return i.append(e,0),i}fixCompositionDOM(t){let e=(t,e)=>{e.flags|=8|(e.children.some((t=>7&t.flags))?1:0),this.markedForComposition.add(e);let i=we.get(t);i&&i!=e&&(i.dom=null),e.setDOM(t)},i=this.childPos(t.range.fromB,1),n=this.children[i.i];e(t.line,n);for(let r=t.marks.length-1;r>=-1;r--)i=n.childPos(i.off,1),n=n.children[i.i],e(r>=0?t.marks[r].node:t.text,n)}updateSelection(t=!1,e=!1){!t&&this.view.observer.selectionRange.focusNode||this.view.observer.readSelectionRange();let i=this.view.root.activeElement,n=i==this.dom,r=!n&&ie(this.dom,this.view.observer.selectionRange)&&!(i&&this.dom.contains(i));if(!(n||e||r))return;let s=this.forceSelection;this.forceSelection=!1;let o=this.view.state.selection.main,a=this.moveToLine(this.domAtPos(o.anchor)),l=o.empty?a:this.moveToLine(this.domAtPos(o.head));if(Ye.gecko&&o.empty&&!this.hasComposition&&(1==(h=a).node.nodeType&&h.node.firstChild&&(0==h.offset||"false"==h.node.childNodes[h.offset-1].contentEditable)&&(h.offset==h.node.childNodes.length||"false"==h.node.childNodes[h.offset].contentEditable))){let t=document.createTextNode("");this.view.observer.ignore((()=>a.node.insertBefore(t,a.node.childNodes[a.offset]||null))),a=l=new xe(t,0),s=!0}var h;let c=this.view.observer.selectionRange;!s&&c.focusNode&&(re(a.node,a.offset,c.anchorNode,c.anchorOffset)&&re(l.node,l.offset,c.focusNode,c.focusOffset)||this.suppressWidgetCursorChange(c,o))||(this.view.observer.ignore((()=>{Ye.android&&Ye.chrome&&this.dom.contains(c.focusNode)&&function(t,e){for(let i=t;i&&i!=e;i=i.assignedSlot||i.parentNode)if(1==i.nodeType&&"false"==i.contentEditable)return!0;return!1}(c.focusNode,this.dom)&&(this.dom.blur(),this.dom.focus({preventScroll:!0}));let t=te(this.view.root);if(t)if(o.empty){if(Ye.gecko){let t=(e=a.node,n=a.offset,1!=e.nodeType?0:(n&&"false"==e.childNodes[n-1].contentEditable?1:0)|(n=(h.left+h.right)/2,n=i;if(Ye.chrome||Ye.gecko){Oe(t,a).getBoundingClientRect().left==h.right&&(n=!i)}if(c<=0)return{node:t,offset:a+(n?1:0)};r=a+(n?1:0),s=c}}}return{node:t,offset:r>-1?r:o>0?t.nodeValue.length:0}}function gn(t,e,i,n=-1){var r,s;let o,a=t.contentDOM.getBoundingClientRect(),l=a.top+t.viewState.paddingTop,{docHeight:h}=t.viewState,{x:c,y:u}=e,p=u-l;if(p<0)return 0;if(p>h)return t.state.doc.length;for(let e=t.viewState.heightOracle.textHeight/2,r=!1;o=t.elementAtHeight(p),o.type!=Je.Text;)for(;p=n>0?o.bottom+e:o.top-e,!(p>=0&&p<=h);){if(r)return i?null:0;r=!0,n=-n}u=l+p;let d=o.from;if(dt.from>=l.from&&t.to<=l.to&&Math.abs(t.from-n)t.from&&a(t.from,r,t,e),o=o?s-i:0,a=s+(a-o),o=s}else if(a=a?s-i:0,o=s+(o-a),a=s}return{from:s,toA:o,toB:a}}(e.state.doc.sliceString(r,a,Ar),i.text,l-r,h);c&&(Ye.chrome&&13==o&&c.toB==c.from+2&&i.text.slice(c.from,c.toB)==Ar+Ar&&c.toB--,n={from:r+c.from,to:r+c.toA,insert:t.of(i.text.slice(c.from,c.toB).split(Ar))})}else r&&(!e.hasFocus&&e.state.facet(Ii)||r.main.eq(s))&&(r=null);if(!n&&!r)return!1;if(!n&&i.typeOver&&!s.empty&&r&&r.main.empty?n={from:s.from,to:s.to,insert:e.state.doc.slice(s.from,s.to)}:n&&n.from>=s.from&&n.to<=s.to&&(n.from!=s.from||n.to!=s.to)&&s.to-s.from-(n.to-n.from)<=4?n={from:s.from,to:s.to,insert:e.state.doc.slice(s.from,n.from).append(n.insert).append(e.state.doc.slice(n.to,s.to))}:(Ye.mac||Ye.android)&&n&&n.from==n.to&&n.from==s.head-1&&/^\. ?$/.test(n.insert.toString())&&"off"==e.contentDOM.getAttribute("autocorrect")?(r&&2==n.insert.length&&(r=_.single(r.main.anchor-1,r.main.head-1)),n={from:s.from,to:s.to,insert:t.of([" "])}):Ye.chrome&&n&&n.from==n.to&&n.from==s.head&&"\n "==n.insert.toString()&&e.lineWrapping&&(r&&(r=_.single(r.main.anchor-1,r.main.head-1)),n={from:s.from,to:s.to,insert:t.of([" "])}),n){if(Ye.ios&&e.inputState.flushIOSKey())return!0;if(Ye.android&&(n.to==s.to&&(n.from==s.from||n.from==s.from-1&&" "==e.state.sliceDoc(n.from,s.from))&&1==n.insert.length&&2==n.insert.lines&&me(e.contentDOM,"Enter",13)||(n.from==s.from-1&&n.to==s.to&&0==n.insert.length||8==o&&n.insert.lengthr))&&e.ranges.push({from:r,to:s})}}a=!1}else if(i&&(s=Co(i.ranges,n.from,n.to)))a=2!=s;else if(!n.type.isAnonymous&&(r=this.nest(n,this.input))&&(n.from