JavaScript

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
Lenguaje de programación de alto nivel

JavaScript (), a menudo abreviado como JS, es un lenguaje de programación que es una de las tecnologías centrales de la World Wide Web, junto con HTML y CSS. A partir de 2022, el 98 % de los sitios web usan JavaScript en el lado del cliente para el comportamiento de la página web, a menudo incorporando bibliotecas de terceros. Todos los principales navegadores web tienen un motor de JavaScript dedicado para ejecutar el código en los usuarios. dispositivos.

JavaScript es un lenguaje compilado de alto nivel, a menudo justo a tiempo, que cumple con el estándar ECMAScript. Tiene escritura dinámica, orientación a objetos basada en prototipos y funciones de primera clase. Es un paradigma múltiple que admite estilos de programación imperativos, funcionales e impulsados por eventos. Tiene interfaces de programación de aplicaciones (API) para trabajar con texto, fechas, expresiones regulares, estructuras de datos estándar y el modelo de objetos de documento (DOM).

El estándar ECMAScript no incluye ninguna entrada/salida (E/S), como instalaciones de red, almacenamiento o gráficos. En la práctica, el navegador web u otro sistema de tiempo de ejecución proporciona API de JavaScript para E/S.

Los motores de JavaScript se usaban originalmente solo en navegadores web, pero ahora son componentes centrales de algunos servidores y una variedad de aplicaciones. El sistema de tiempo de ejecución más popular para este uso es Node.js.

Aunque Java y JavaScript son similares en nombre, sintaxis y bibliotecas estándar respectivas, los dos lenguajes son distintos y difieren mucho en diseño.

Historia

Creación en Netscape

El primer navegador web popular con una interfaz gráfica de usuario, Mosaic, se lanzó en 1993. Accesible para personas sin conocimientos técnicos, desempeñó un papel destacado en el rápido crecimiento de la naciente World Wide Web. Los principales desarrolladores de Mosaic fundaron entonces la corporación Netscape, que lanzó un navegador más refinado, Netscape Navigator, en 1994. Rápidamente se convirtió en el más utilizado.

Durante estos años formativos de la web, las páginas web solo podían ser estáticas y carecían de la capacidad de comportamiento dinámico una vez que la página se cargaba en el navegador. Había un deseo en la floreciente escena del desarrollo web de eliminar esta limitación, por lo que en 1995, Netscape decidió agregar un lenguaje de secuencias de comandos a Navigator. Siguieron dos caminos para lograrlo: colaborar con Sun Microsystems para incorporar el lenguaje de programación Java y, al mismo tiempo, contratar a Brendan Eich para incorporar el lenguaje Scheme.

La gerencia de Netscape pronto decidió que la mejor opción era que Eich diseñara un nuevo lenguaje, con una sintaxis similar a Java y menos como Scheme u otros lenguajes de secuencias de comandos existentes. Aunque el nuevo lenguaje y la implementación de su intérprete se llamaron LiveScript cuando se envió por primera vez como parte de una versión beta de Navigator en septiembre de 1995, el nombre se cambió a JavaScript para el lanzamiento oficial en diciembre.

La elección del nombre de JavaScript ha causado confusión, lo que implica que está directamente relacionado con Java. En ese momento, el auge de las puntocom había comenzado y Java era el nuevo lenguaje de moda, por lo que Eich consideró que el nombre de JavaScript era una estratagema de marketing de Netscape.

Adopción por Microsoft

Microsoft debutó con Internet Explorer en 1995, lo que provocó una guerra de navegadores con Netscape. En el frente de JavaScript, Microsoft realizó ingeniería inversa del intérprete de Navigator para crear uno propio, llamado JScript.

JScript se lanzó por primera vez en 1996, junto con soporte inicial para CSS y extensiones para HTML. Cada una de estas implementaciones era notablemente diferente de sus contrapartes en Navigator. Estas diferencias dificultaron que los desarrolladores hicieran que sus sitios web funcionaran bien en ambos navegadores, lo que llevó al uso generalizado de "mejor visto en Netscape" y "mejor visto en Internet Explorer" logotipos durante varios años.

El surgimiento de JScript

En noviembre de 1996, Netscape presentó JavaScript a Ecma International, como punto de partida para una especificación estándar que todos los proveedores de navegadores pudieran cumplir. Esto condujo al lanzamiento oficial de la primera especificación del lenguaje ECMAScript en junio de 1997.

El proceso de estándares continuó durante algunos años, con el lanzamiento de ECMAScript 2 en junio de 1998 y ECMAScript 3 en diciembre de 1999. El trabajo en ECMAScript 4 comenzó en 2000.

Mientras tanto, Microsoft ganó una posición cada vez más dominante en el mercado de navegadores. A principios de la década de 2000, la cuota de mercado de Internet Explorer alcanzó el 95 %. Esto significó que JScript se convirtió en el estándar de facto para las secuencias de comandos del lado del cliente en la Web.

Microsoft participó inicialmente en el proceso de estándares e implementó algunas propuestas en su lenguaje JScript, pero finalmente dejó de colaborar en el trabajo de Ecma. Por lo tanto, ECMAScript 4 fue suspendido.

Crecimiento y estandarización

Durante el período de dominio de Internet Explorer a principios de la década de 2000, las secuencias de comandos del lado del cliente estaban estancadas. Esto empezó a cambiar en 2004, cuando el sucesor de Netscape, Mozilla, lanzó el navegador Firefox. Firefox fue bien recibido por muchos, arrebatándole una importante cuota de mercado a Internet Explorer.

En 2005, Mozilla se unió a ECMA International y comenzó a trabajar en el estándar ECMAScript para XML (E4X). Esto llevó a Mozilla a trabajar en conjunto con Macromedia (posteriormente adquirida por Adobe Systems), quienes estaban implementando E4X en su lenguaje ActionScript 3, que estaba basado en un borrador de ECMAScript 4. El objetivo se convirtió en estandarizar ActionScript 3 como el nuevo ECMAScript 4. Con este fin, Adobe Systems lanzó la implementación de Tamarin como un proyecto de código abierto. Sin embargo, Tamarin y ActionScript 3 eran demasiado diferentes de las secuencias de comandos del lado del cliente establecidas y, sin la cooperación de Microsoft, ECMAScript 4 nunca llegó a buen término.

Mientras tanto, se estaban produciendo desarrollos muy importantes en las comunidades de código abierto no afiliadas al trabajo de ECMA. En 2005, Jesse James Garrett publicó un libro blanco en el que acuñó el término Ajax y describió un conjunto de tecnologías, de las cuales JavaScript era la columna vertebral, para crear aplicaciones web donde los datos se pueden cargar en segundo plano, evitando la necesidad de una página completa. recargas Esto provocó un período de renacimiento de JavaScript, encabezado por bibliotecas de código abierto y las comunidades que se formaron a su alrededor. Se crearon muchas bibliotecas nuevas, incluidas jQuery, Prototype, Dojo Toolkit y MooTools.

Google presentó su navegador Chrome en 2008, con el motor JavaScript V8 que era más rápido que su competencia. La innovación clave fue la compilación justo a tiempo (JIT), por lo que otros proveedores de navegadores necesitaban revisar sus motores para JIT.

En julio de 2008, estos partidos dispares se reunieron para una conferencia en Oslo. Esto condujo al eventual acuerdo a principios de 2009 para combinar todo el trabajo relevante e impulsar el lenguaje. El resultado fue el estándar ECMAScript 5, lanzado en diciembre de 2009.

Alcanzar la madurez

El trabajo ambicioso en el lenguaje continuó durante varios años, culminando en una extensa colección de adiciones y refinamientos que se formalizaron con la publicación de ECMAScript 6 en 2015.

La creación de Node.js en 2009 por parte de Ryan Dahl provocó un aumento significativo en el uso de JavaScript fuera de los navegadores web. Node combina el motor V8, un bucle de eventos y las API de E/S, lo que proporciona un sistema de tiempo de ejecución de JavaScript independiente. A partir de 2018, millones de desarrolladores habían utilizado Node y npm tenía la mayor cantidad de módulos de cualquier administrador de paquetes del mundo.

Actualmente, el borrador de la especificación ECMAScript se mantiene abiertamente en GitHub, y las ediciones se producen a través de instantáneas anuales periódicas. Las posibles revisiones del lenguaje se examinan a través de un proceso de propuesta integral. Ahora, en lugar de los números de edición, los desarrolladores verifican el estado de las próximas funciones individualmente.

El ecosistema de JavaScript actual tiene muchas bibliotecas y marcos, prácticas de programación establecidas y un uso considerable de JavaScript fuera de los navegadores web. Además, con el auge de las aplicaciones de una sola página y otros sitios web con gran cantidad de JavaScript, se han creado varios transpiladores para ayudar en el proceso de desarrollo.

Marca

"JavaScript" es una marca comercial de Oracle Corporation en los Estados Unidos. La marca comercial se emitió originalmente a Sun Microsystems el 6 de mayo de 1997 y se transfirió a Oracle cuando adquirieron Sun en 2009.

Uso del lado del cliente del sitio web

JavaScript es el lenguaje de secuencias de comandos dominante del lado del cliente de la Web, y el 98 % de todos los sitios web (mediados de 2022) lo utilizan para este fin. Los scripts están incrustados o incluidos en documentos HTML e interactúan con el DOM. Todos los principales navegadores web tienen un motor de JavaScript integrado que ejecuta el código en el dispositivo del usuario.

Ejemplos de comportamiento con guión

  • Cargar nuevo contenido de página web sin volver a cargar la página, a través de Ajax o un WebSocket. Por ejemplo, los usuarios de redes sociales pueden enviar y recibir mensajes sin salir de la página actual.
  • Animaciones de página web, tales como desvanecer objetos dentro y fuera, cambiar el tamaño y moverlos.
  • Jugar juegos de navegador.
  • Controlando la reproducción de los medios de transmisión.
  • Generando anuncios pop-up o cajas de alerta.
  • Validar los valores de entrada de un formulario web antes de enviar los datos a un servidor web.
  • Registro de datos sobre el comportamiento del usuario y luego enviarlo a un servidor. El propietario del sitio web puede utilizar estos datos para análisis, seguimiento de anuncios y personalización.
  • Redireccionar un usuario a otra página.
  • Guardar y recuperar datos en el dispositivo del usuario, a través de los estándares de almacenamiento o IndexedDB.

Bibliotecas y marcos

Más del 80 % de los sitios web utilizan una biblioteca de JavaScript o un marco web de terceros para sus secuencias de comandos del lado del cliente.

jQuery es, con mucho, la biblioteca más popular, utilizada por más del 75% de los sitios web. Facebook creó la biblioteca React para su sitio web y luego la lanzó como fuente abierta; otros sitios, incluido Twitter, ahora lo usan. Asimismo, el marco Angular creado por Google para sus sitios web, incluidos YouTube y Gmail, ahora es un proyecto de código abierto utilizado por otros.

Por el contrario, el término "Vanilla JS" se acuñó para sitios web que no usan bibliotecas o marcos, sino que dependen completamente de la funcionalidad estándar de JavaScript.

Otro uso

El uso de JavaScript se ha expandido más allá de las raíces de su navegador web. Los motores de JavaScript ahora están integrados en una variedad de otros sistemas de software, tanto para implementaciones de sitios web del lado del servidor como para aplicaciones que no son de navegador.

Los primeros intentos de promover el uso de JavaScript del lado del servidor fueron Netscape Enterprise Server e Internet Information Services de Microsoft, pero eran nichos pequeños. El uso del lado del servidor eventualmente comenzó a crecer a fines de la década de 2000, con la creación de Node.js y otros enfoques.

Electron, Cordova, React Native y otros marcos de aplicación se han utilizado para crear muchas aplicaciones con comportamiento implementado en JavaScript. Otras aplicaciones que no son de navegador incluyen la compatibilidad con Adobe Acrobat para crear secuencias de comandos de documentos PDF y extensiones de GNOME Shell escritas en JavaScript.

JavaScript ha comenzado a aparecer recientemente en algunos sistemas integrados, generalmente aprovechando Node.js.

Características

Las siguientes funciones son comunes a todas las implementaciones que cumplen con ECMAScript, a menos que se especifique lo contrario de manera explícita.

Imperativa y estructurada

(feminine)

JavaScript es compatible con gran parte de la sintaxis de programación estructurada de C (por ejemplo, sentencias if, bucles while, sentencias switch, sentencias do while bucles, etc.). Una excepción parcial es el alcance: originalmente, JavaScript solo tenía un alcance de función con var; el alcance de bloque se agregó en ECMAScript 2015 con las palabras clave let y const. Al igual que C, JavaScript hace una distinción entre expresiones y sentencias. Una diferencia sintáctica con C es la inserción automática de punto y coma, que permite omitir los puntos y coma (que terminan las declaraciones).

Débilmente escrita

(feminine)

JavaScript tiene tipos débiles, lo que significa que ciertos tipos se convierten implícitamente según la operación utilizada.

  • El binario + operador lanza ambos operandos a una cadena a menos que ambos operandos sean números. Esto se debe a que el operador de adición se duplica como operador de concatenación
  • El binario - operador siempre lanza ambos operandos a un número
  • Ambos operadores no deseados (+, -) siempre lanzar el operand a un número

Los valores se convierten en cadenas como las siguientes:

  • Las cuerdas se quedan como
  • Números se convierten a su representación de cadenas
  • Arrays tiene sus elementos lanzados a cadenas después de las cuales se unen por comas (,)
  • Otros objetos se convierten en la cadena [object Object] Donde Object es el nombre del constructor del objeto

Los valores se transforman en números convirtiéndolos en cadenas y luego transformando las cadenas en números. Estos procesos se pueden modificar definiendo las funciones toString y valueOf en el prototipo para la conversión de cadenas y números respectivamente.

JavaScript ha recibido críticas por la forma en que implementa estas conversiones, ya que la complejidad de las reglas puede confundirse con incoherencias. Por ejemplo, al agregar un número a una cadena, el número se convertirá en una cadena antes de realizar la concatenación, pero al restar un número de una cadena, la cadena se convertirá en un número antes de realizar la resta.

Conversiones de tipo JavaScript
izquierda que operan operador operando a la derecha resultado
[] (dispositivo vacío) +[] (dispositivo vacío) "" (la cuerda vacía)
[] (dispositivo vacío) +{} (objeto vacío) "[object Object]" (cadena)
false (boolean) +[] (dispositivo vacío) "false" (cadena)
"123"(cadena) +1 (número) "1231" (cadena)
"123" (cadena) -1 (número) 122 (número)
"123" (cadena) -"abc" (cadena) NaN (número)

A menudo también se menciona {} + [] dando como resultado 0 (número). Esto es engañoso: el {} se interpreta como un bloque de código vacío en lugar de un objeto vacío, y el operador unario restante + convierte la matriz vacía en un número. Si envuelve la expresión entre paréntesis ({} + []), los corchetes se interpretan como un objeto vacío y el resultado de la expresión es "[objeto Objeto]&# 34; como se esperaba.

Dinámica

(feminine)
Tipografía
JavaScript se escribe dinámicamente como la mayoría de otros lenguajes de scripting. Un tipo se asocia con un valor más que una expresión. Por ejemplo, una variable inicialmente ligada a un número puede ser reasignada a una cadena. JavaScript admite varias maneras de probar el tipo de objetos, incluyendo el tipo de pato.
Evaluación del tiempo de ejecución
JavaScript incluye un eval función que puede ejecutar declaraciones proporcionadas como cadenas a tiempo de ejecución.

Orientación a objetos (basada en prototipos)

Douglas Crockford describe la herencia de prototipos en JavaScript como:

Haces objetos prototipos, y luego... haces nuevas instancias. Los objetos son mutables en JavaScript, por lo que podemos aumentar las nuevas instancias, dándoles nuevos campos y métodos. Estos pueden actuar como prototipos para objetos aún más nuevos. No necesitamos clases para hacer un montón de objetos similares... Los objetos heredan de objetos. ¿Qué podría estar más orientado al objeto que eso?

En JavaScript, un objeto es una matriz asociativa, aumentada con un prototipo (ver más abajo); cada clave proporciona el nombre de una propiedad de objeto, y hay dos formas sintácticas de especificar dicho nombre: notación de puntos (obj.x = 10) y notación de corchetes (obj['x'] = 10). Una propiedad se puede agregar, volver a vincular o eliminar en tiempo de ejecución. La mayoría de las propiedades de un objeto (y cualquier propiedad que pertenezca a la cadena de herencia del prototipo de un objeto) se pueden enumerar mediante un bucle for...in.

Prototipos
JavaScript utiliza prototipos donde muchos otros lenguajes orientados a objetos utilizan clases de herencia. Es posible simular muchas características basadas en clases con prototipos en JavaScript.
Funciones como constructores de objetos
Funciones dobles como constructores de objetos, junto con su papel típico. Prefijo de una llamada de función con nuevo creará una instancia de un prototipo, heredando propiedades y métodos del constructor (incluyendo propiedades del Object prototipo). ECMAScript 5 ofrece Object.create método, permitiendo la creación explícita de una instancia sin heredar automáticamente del Object prototipo (ambientes más antiguos pueden asignar el prototipo a null). El constructor prototype propiedad determina el objeto utilizado para el prototipo interno del nuevo objeto. Se pueden añadir nuevos métodos modificando el prototipo de la función utilizada como constructor. constructores incorporados de JavaScript, como Array o Object, también tienen prototipos que pueden ser modificados. Mientras que es posible modificar el Object prototipo, generalmente se considera mala práctica porque la mayoría de los objetos en JavaScript heredarán métodos y propiedades del Object prototipo, y pueden no esperar que el prototipo sea modificado.
Funciones como métodos
A diferencia de muchos lenguajes orientados a objetos, no hay distinción entre una definición de función y una definición de método. Más bien, la distinción ocurre durante la llamada de función: cuando una función se llama como un método de un objeto, la función es local esto la palabra clave está ligada a ese objeto para esa invocación.

Funcional

Las funciones de JavaScript son de primera clase; una función se considera un objeto. Como tal, una función puede tener propiedades y métodos, como .call() y .bind(). Una función anidada es una función definida dentro de otra función. Se crea cada vez que se invoca la función externa. Además, cada función anidada forma un cierre léxico: el alcance léxico de la función externa (incluida cualquier constante, variable local o valor de argumento) se convierte en parte del estado interno de cada objeto de función interna, incluso después de que concluye la ejecución de la función externa.. JavaScript también admite funciones anónimas.

Delegado

JavaScript admite la delegación implícita y explícita.

Funciones como roles (Traits y Mixins)
JavaScript apoya nativamente varias implementaciones basadas en funciones de patrones de rol como Traits y Mixins. Tal función define el comportamiento adicional por al menos un método vinculado al this palabra clave dentro de su function cuerpo. A continuación, debe delegarse explícitamente un papel call o apply a objetos que necesitan tener comportamiento adicional que no se comparte a través de la cadena prototipo.
Composición y herencia de objetos
Mientras que la delegación basada en funciones explícita cubre la composición en JavaScript, la delegación implícita ya sucede cada vez que se camina la cadena prototipo para, por ejemplo, encontrar un método que pueda estar relacionado con pero no es directamente propiedad de un objeto. Una vez que se encuentra el método se llama dentro del contexto de este objeto. Así, la herencia en JavaScript está cubierta por un automatismo de delegación que está vinculada a la propiedad prototipo de las funciones de constructor.

Varios

JavaScript es un lenguaje de índice cero.

Entorno en tiempo de ejecución
Normalmente, JavaScript se basa en un entorno de tiempo de ejecución (por ejemplo, un navegador web) para proporcionar objetos y métodos mediante los cuales los scripts pueden interactuar con el medio ambiente (por ejemplo, una página web DOM). Estos ambientes están unidos. JavaScript también se basa en el entorno de tiempo de ejecución para proporcionar la capacidad de incluir/importar scripts (por ejemplo, HTML elementos). Esto no es una característica del lenguaje per se, pero es común en la mayoría de implementaciones JavaScript. JavaScript procesa mensajes de una cola a la vez. JavaScript llama una función asociada a cada nuevo mensaje, creando un marco de llamada con los argumentos de la función y las variables locales. La pila de llamadas se encoge y crece según las necesidades de la función. Cuando la pila de llamadas está vacía al completar la función, JavaScript procede al siguiente mensaje en la cola. Esto se llama el bucle del evento, descrito como "corrido a la terminación" porque cada mensaje se procesa completamente antes de que se considere el siguiente mensaje. Sin embargo, el modelo de concurrencia del idioma describe el bucle del evento como no bloqueo: la entrada / salida del programa se realiza utilizando eventos y funciones de callback. Esto significa, por ejemplo, que JavaScript puede procesar un clic del ratón mientras espera una consulta de bases de datos para devolver información.
Funciones variables
Se puede pasar un número indefinido de parámetros a una función. La función puede acceder a ellos a través de parámetros formales y también a través del local arguments objeto. Las funciones varídicas también se pueden crear utilizando bind método.
Array y objetos literales
Como muchos lenguajes de scripting, arrays y objetos (arrays asociativos en otros idiomas) se pueden crear cada uno con una sintaxis atajos succinct. De hecho, estos literales forman la base del formato de datos JSON.
Expresiones periódicas
JavaScript también soporta expresiones regulares de una manera similar a Perl, que proporcionan una sintaxis concisa y potente para la manipulación de texto que es más sofisticada que las funciones de cadena incorporadas.
Promesas y Async/await
JavaScript soporta promesas y Async/await para manejar operaciones asincrónicas. Un objeto de promesa incorporado proporciona funcionalidad para manejar promesas y asociar controladores con el resultado final de una acción asincrónica. Recientemente se implantaron métodos combinadores en la especificación JavaScript, que permite a los desarrolladores combinar múltiples promesas de JavaScript y realizar operaciones basadas en diferentes escenarios. Los métodos introducidos son: Promise.race, Promise.all, Promise.all Asentado y prometido. Async/await permite que una función asincrónica y no bloqueadora sea estructurada de una manera similar a una función sincronizada ordinaria. Se puede escribir código asincrónico y no bloqueante, con una sobrecarga mínima, estructurado similar al código tradicional sincrónico, bloqueo.

Extensiones específicas del proveedor

Históricamente, algunos motores de JavaScript admitían estas características no estándar:

  • condicional catch cláusulas (como Java)
  • comprensiones y expresiones generadoras (como Python)
  • expresiones de función concisa (function(args) expr; esta sintaxis experimental predated arrow functions)
  • ECMAScript para XML (E4X), una extensión que añade soporte XML nativo a ECMAScript (sin soporte en Firefox desde la versión 21)

Sintaxis

Ejemplos simples

Las variables en JavaScript se pueden definir utilizando las palabras clave var, let o const. Las variables definidas sin palabras clave se definirán en el ámbito global.

// Declara una variable con función llamada `x`, y asigna implícitamente la// valor especial " no definido ". Variables sin valor son automáticamente// fijado para indefinido.// var generalmente se considera mala práctica y dejar y const son generalmente preferidos.Var x;// Las variables se pueden configurar manualmente para que no se definanDeja x2 = indefinidos;// Declara una variable bloqueada llamada 'y', y lo establece implícitamente// `undefinido`. La palabra clave " vamos " fue introducida en ECMAScript 2015.Deja Sí.;// Declara una variable bloqueada, no razonable llamada `z`, y la establece para// una cadena literal. La palabra clave "const" también fue introducida en ECMAScript 2015,// y debe ser asignado explícitamente.// La palabra clave `const` significa constante, por lo que la variable no puede ser reasignada// como el valor es `constant`.const z = "¡Este valor no puede ser reasignado!";// Declara una variable global y asigna 3. Esto se considera generalmente// mala práctica, y no funcionará si el modo estricto está encendido.t = 3;// Declara una variable llamada `myNumber`, y asigna un número literal (el valor// `2`) a ella.Deja myNumber = 2;// Reasigna `myNumber`, fijando a una cadena literal (el valor `'foo'').// JavaScript es un lenguaje de tipo dinámico, por lo que es legal.myNumber = "foo";

Tenga en cuenta los comentarios en el ejemplo anterior, todos los cuales fueron precedidos por dos barras diagonales.

No hay una funcionalidad de entrada/salida integrada en JavaScript, sino que la proporciona el entorno de tiempo de ejecución. La especificación ECMAScript en la edición 5.1 menciona que "no hay disposiciones en esta especificación para la entrada de datos externos o la salida de resultados calculados". Sin embargo, la mayoría de los entornos de tiempo de ejecución tienen un objeto console que se puede usar para imprimir la salida. Aquí hay un programa Hello World minimalista en JavaScript en un entorno de tiempo de ejecución con un objeto de consola:

consola.log()"¡Hola, Mundo!");

En documentos HTML, se requiere un programa como este para una salida:

// Los nodos de texto se pueden hacer utilizando el método "escribir".// Esto es fructífero, ya que puede sobreescribir el documento si el documento está completamente cargado.documento.escribir()'foo ');// También se pueden hacer elementos. Primero, tienen que ser creados en el DOM.const myElem = documento.crear Elemento()'span ');// Atributos como clases y el id también se pueden establecermyElem.clase Lista.añadir()'foo ');myElem.id = 'bar ';// Después de configurar esto, la etiqueta se verá así: 'Clase de resultados="foo" id="bar" data-attr="baz" `myElem.setAttribute()'data-attr ', 'baz '); // Que también podría ser escrito como `miElem.dataset.attr = 'baz'`// Finalmente, añádelo como elemento de niño al неbody ratio en el HTMLdocumento.cuerpo.apéndiceChild()myElem);// Los elementos pueden ser aprehendidos con querySelector para un elemento, o querySelectorAll para múltiples elementos con los que se puede buclear para cada unodocumento.querySelector()'.clase '); // Seleccione el primer elemento con la clase "clase"documento.querySelector()################################################################################################################################################################################################################################################################ '); // Seleccione el primer elemento con una "id" de "id"documento.querySelector()'[data-other] '); // Seleccione el primer elemento con el atributo "data-other"documento.querySelectorAll()'.multiple '); // Devuelve un rayo de todos los elementos con la clase "multiple"

Una función recursiva simple para calcular el factorial de un número natural:

función factorial()n) {} // Comprobando el argumento para la legitimidad. Factorial se define para enteros positivos. si ()isNa()n) {} consola.error()"No se permite un argumento numérico".); retorno Nan; // El valor especial: no un número } si ()n == 0) retorno 1; // 0 = 1 si ()n . 0) retorno indefinidos; // Factorial of negative numbers is not defined. si ()n % 1) {} consola.Warn()`${n} será redondeado al entero más cercano. Para los no-integers consideran usar función gamma en su lugar. `); n = Matemáticas.redonda()n); } // Las comprobaciones anteriores no deben repetirse en la recursión, por lo que definir la parte recursiva real por separado a continuación. // La siguiente línea es una expresión de función para calcular repetidamente el factorial. Utiliza la sintaxis de flecha introducida en ES6. const recursivamenteComputar = a = a  1 ? a * recursivamenteComputar()a - 1) : 1; // Tenga en cuenta el uso del operador ternario `?`. retorno recursivamenteComputar()n);}factorial()3); // Devoluciones 6

Una función anónima (o lambda):

const contra = función() {} Deja Cuenta = 0; retorno función() {} retorno ++Cuenta; }};const x = contra();x(); // Devoluciones 1x(); // Devoluciones 2x(); // Devoluciones 3

Este ejemplo muestra que, en JavaScript, los cierres de funciones capturan sus variables no locales por referencia.

Las funciones de flecha se introdujeron por primera vez en la sexta edición: ECMAScript 2015. Acortan la sintaxis para escribir funciones en JavaScript. Las funciones de flecha son anónimas, por lo que se necesita una variable para hacer referencia a ellas con el fin de invocarlas después de su creación, a menos que esté entre paréntesis y se ejecute inmediatamente.

Ejemplo de función de flecha:

// Las funciones de flecha nos permiten omitir la palabra clave de la función.// Aquí `long_example` apunta a un valor de función anónimo.const long_example = ()entrada1, input2) = {} consola.log()"¡Hola, Mundo!"); const Producto = entrada1 + input2; retorno Producto;};// Si no hay frenos, la función de flecha simplemente devuelve la expresión// Así que aquí está (input1 + entrada2)const short_example = ()entrada1, input2) = entrada1 + input2;long_example()2, 3); // Imprime "¡Hola, Mundo!" y devuelve 5short_example()2, 5); // Devoluciones 7// Si una función de flecha tiene sólo un parámetro, los paréntesis pueden ser eliminados.const No. = entrada = entrada + 2;No.()3); // Devoluciones 5// Una función de flecha, como otras definiciones de función, se puede ejecutar en la misma declaración que se crean.// Esto es útil cuando se escriben bibliotecas para evitar llenar el alcance global, y para los cierres.Deja tres = ()a, b) = a + b) ()1, 2);const genera_multiplier_función = a = ()b = isNa()b) Silencio !b ? a : a*=b);const 5_multiples = genera_multiplier_función()5); // El argumento suministrado "semillas" la expresión y es retenido por a.5_multiples()1); // Devoluciones 55_multiples()3); // Devoluciones 155_multiples()4); // Devoluciones 60

En JavaScript, los objetos se pueden crear como instancias de una clase.

Ejemplo de clase de objeto:

clase Ball {} constructor()radio) {} esto.radio = radio; esto.zona = Matemáticas.PI * () radio # 2 ); } // Clases (y por lo tanto objetos) pueden contener funciones conocidas como métodos show() {} consola.log()esto.radio); }};const myBall = nuevo Ball()5); // Crea una nueva instancia del objeto de bola con radio 5myBall.radio++; // Las propiedades de objetos generalmente se pueden modificar desde el exteriormyBall.show(); // Usando los registros de función "Mostrar" heredados "6"

En JavaScript, los objetos se pueden instanciar directamente desde una función.

Ejemplo funcional de objeto:

función Ball()radio) {} const zona = Matemáticas.PI * () radio # 2 ); const obj = {} radio, zona }; // Los objetos son mutables, y las funciones se pueden añadir como propiedades. obj.show = () = consola.log()obj.radio); retorno obj;};const myBall = Ball()5); // Crea un nuevo objeto de bola con radio 5. Ninguna palabra clave "nueva" necesaria.myBall.radio++; // La propiedad de instancia puede ser modificada.myBall.show(); // Utilizando los registros de función "Mostrar" "6" - el nuevo valor de instancia.

Demostración de la función Variádica (arguments es una variable especial):

función suma() {} Deja x = 0; para ()Deja i = 0; i . argumentaciones.longitud; ++i) x += argumentaciones[i]; retorno x;}suma()1, 2); // Devoluciones 3suma()1, 2, 3); // Devoluciones 6// A partir de ES6, utilizando el operador de resto.función suma(...args) {} retorno args.reducción()a,b) = a+b);}suma()1, 2); // Devoluciones 3suma()1, 2, 3); // Devoluciones 6

Las expresiones de función invocadas inmediatamente se utilizan a menudo para crear cierres. Los cierres permiten recopilar propiedades y métodos en un espacio de nombres y hacer que algunos de ellos sean privados:

Deja contra = ()función() {} Deja i = 0; / Propiedad privada retorno {} / Métodos públicos #: función() {} alerta()i); } set: función()valor) {} i = valor; } aumento: función() {} alerta()++i); } };})(); // Módulocontra.#(); // Devoluciones 0contra.set()6);contra.aumento(); // Devoluciones 7contra.aumento(); // Devoluciones 8

Los objetos generadores (en forma de funciones generadoras) proporcionan una función que se puede llamar, salir y volver a ingresar mientras se mantiene el contexto interno (estado).

función* rawCounter() {} rendimiento 1; rendimiento 2;}función* DynamicCounter() {} Deja Cuenta = 0; mientras()verdadero) {} // No se recomienda utilizar mientras que los bucles verdaderos en la mayoría de los casos. rendimiento ++Cuenta; }}// Instancesconst contra1 = rawCounter();const contra2 = DynamicCounter();// Aplicacióncontra1.siguiente(); // {valor: 1, made: false}contra1.siguiente(); // {valor: 2, made: false}contra1.siguiente(); // {valor: undefinido, hecho: verdadero}contra2.siguiente(); // {valor: 1, made: false}contra2.siguiente(); // {valor: 2, made: false}contra2.siguiente(); // {valor: 3, hecho: falso}Definitivamente


JavaScript puede exportar e importar desde módulos:

Ejemplo de exportación:

/* mymodule.js */// Esta función sigue siendo privada, ya que no se exportaDeja suma = ()a, b) = {} retorno a + b;}// Variables de exportaciónExportación Deja Nombre = 'Alice ';Exportación Deja Edad = 23;// Funciones de exportación nombradasExportación función añadir()num1, num2) {} retorno num1 + num2;}// Clase de exportaciónExportación clase Multiplicación {} constructor()num1, num2) {} esto.num1 = num1; esto.num2 = num2; } añadir() {} retorno suma()esto.num1, esto.num2); }}

Ejemplo de importación:

// Importar una propiedadimportación {} añadir } desde './mymodule.js ';consola.log()añadir()1, 2));// 3// Importar múltiples propiedadesimportación {} Nombre, Edad } desde './mymodule.js ';consola.log()Nombre, Edad);// título "Alice", 23// Importar todas las propiedades de un móduloimportación * desde './module.js 'consola.log()Nombre, Edad);// título "Alice", 23consola.log()añadir()1,2));// 3

Ejemplo más avanzado

Este código de muestra muestra varias características de JavaScript.

/* Encuentra el múltiplo común más bajo (LCM) de dos números */función LCMCalculator()x, Sí.) {} // función constructor si ()isNa()x*Sí.) tiro nuevo TipoError()"No se permiten argumentos numéricos".); const cheque Int = función()x) {} // función interna si ()x % 1 ! 0) tiro nuevo TipoError()x + "no es un entero"); retorno x; }; esto.a = cheque Int()x) // semicolons ^^^^^^ son opcionales, una nueva línea es suficiente esto.b = cheque Int()Sí.);}// El prototipo de casos de objetos creados por un constructor es// la propiedad del constructor "prototipo".LCMCalculator.prototipo = {} // objeto literal constructor: LCMCalculator, // al reasignar un prototipo, establecer la propiedad constructor apropiadamente gcd: función() {} // método que calcula el mayor divisor común // algoritmo euclidiano: Deja a = Matemáticas.abdominales()esto.a), b = Matemáticas.abdominales()esto.b), t; si ()a . b) {} // variables de intercambio // t = b; b = a; a = t; [a, b] = [b, a]; // intercambio mediante asignación destructora (ES6) } mientras ()b ! 0) {} t = b; b = a % b; a = t; } // Sólo hay que calcular GCD una vez, así que "redefine" este método. // (En realidad no la redefinición - se define en la instancia misma, Así que esto. gcd se refiere a esta "redefinición" en lugar de LCMCalculator.prototype.gcd. // Tenga en cuenta que esto conduce a un resultado equivocado si los miembros del objeto LCMCalculator "a" y/o "b" se alteran después.) // También, 'gcd' === "gcd", esto ['gcd'] == this.gcd esto['gcd '] = función() {} retorno a; }; retorno a; } // Los nombres de propiedades de objetos se pueden especificar por cadenas delimitadas por citas dobles (") o individuales ('). "lcm": función() {} // Los nombres variables no chocan con las propiedades del objeto, por ejemplo, TENLcm La vida no es TENthis.lcm sometida. // no utilizar Нthis.a*this.b Deja lcm = esto.a / esto.gcd() * esto.b; // Sólo hay que calcular lcm una vez, así que "redefine" este método. esto.lcm = función() {} retorno lcm; }; retorno lcm; } // Los métodos también se pueden declarar utilizando la sintaxis es6 toString() {} // Utilizando tanto los literales de plantilla de es6 como el (+) operador para concatenar valores retorno `LCMCalculator: a = ${esto.a}, b = + esto.b; }};// Definir función de salida genérica; esta implementación sólo funciona para navegadores webfunción Producto()x) {} documento.cuerpo.apéndiceChild()documento.crearTextNode()x)); documento.cuerpo.apéndiceChild()documento.crear Elemento()'br '));}// Nota: El mapa() y paraCada() de Array se definen en JavaScript 1.6.// Se utilizan aquí para demostrar la naturaleza funcional inherente a JavaScript.[ [25, 55] [21, 56] [22, 58] [28, 56]].mapa()función()par) {} // matriz literal + función de asignación retorno nuevo LCMCalculator()par[0] par[1]);}).especie()a, b) = a.lcm() - b.lcm()) // ordenar con esta función comparativa; = es una forma corta de una función, llamada "función estrecha" .para cada uno()Resultado);función Resultado()obj) {} Producto()obj + ", gcd = " + obj.gcd() + ", lcm = " + obj.lcm());}

El siguiente resultado debe mostrarse en la ventana del navegador.

LCMCalculator: a = 28, b = 56, gcd = 28, lcm = 56
LCMCalculator: a = 21, b = 56, gcd = 7, lcm = 168
LCMCalculator: a = 25, b = 55, gcd = 5, lcm = 275
LCMCalculator: a = 22, b = 58, gcd = 2, lcm = 638

Seguridad

JavaScript y el DOM brindan la posibilidad de que los autores maliciosos entreguen secuencias de comandos para que se ejecuten en una computadora cliente a través de la Web. Los autores de navegadores minimizan este riesgo utilizando dos restricciones. En primer lugar, los scripts se ejecutan en un espacio aislado en el que solo pueden realizar acciones relacionadas con la Web, no tareas de programación de propósito general como la creación de archivos. En segundo lugar, las secuencias de comandos están restringidas por la política del mismo origen: las secuencias de comandos de un sitio web no tienen acceso a información como nombres de usuario, contraseñas o cookies enviadas a otro sitio. La mayoría de los errores de seguridad relacionados con JavaScript son infracciones de la misma política de origen o de la zona de pruebas.

Hay subconjuntos de JavaScript general (ADsafe, ECMAScript seguro (SES)) que brindan mayores niveles de seguridad, especialmente en código creado por terceros (como anuncios). Closure Toolkit es otro proyecto para la incrustación y el aislamiento seguros de JavaScript y HTML de terceros.

La política de seguridad de contenido es el principal método previsto para garantizar que solo se ejecute código de confianza en una página web.

Vulnerabilidades entre sitios

Un problema de seguridad común relacionado con JavaScript es el cross-site scripting (XSS), una infracción de la política del mismo origen. Las vulnerabilidades XSS ocurren cuando un atacante puede hacer que un sitio web de destino, como un sitio web de banca en línea, incluya un script malicioso en la página web que se presenta a la víctima. El script de este ejemplo puede acceder a la aplicación bancaria con los privilegios de la víctima, lo que podría revelar información secreta o transferir dinero sin la autorización de la víctima. Una solución a las vulnerabilidades XSS es utilizar HTML escape siempre que se muestren datos que no sean de confianza.

Algunos navegadores incluyen protección parcial contra ataques XSS reflejados, en los que el atacante proporciona una URL que incluye un script malicioso. Sin embargo, incluso los usuarios de esos navegadores son vulnerables a otros ataques XSS, como aquellos en los que el código malicioso se almacena en una base de datos. Solo el diseño correcto de las aplicaciones web en el lado del servidor puede prevenir XSS por completo.

Las vulnerabilidades XSS también pueden ocurrir debido a errores de implementación por parte de los autores del navegador.

Otra vulnerabilidad entre sitios es la falsificación de solicitudes entre sitios (CSRF). En CSRF, el código en el sitio de un atacante engaña al navegador de la víctima para que realice acciones que el usuario no pretendía en un sitio de destino (como transferir dinero en un banco). Cuando los sitios de destino se basan únicamente en cookies para la autenticación de solicitudes, las solicitudes que se originan a partir del código en el sitio del atacante pueden llevar las mismas credenciales de inicio de sesión válidas del usuario iniciador. En general, la solución a CSRF es requerir un valor de autenticación en un campo de formulario oculto, y no solo en las cookies, para autenticar cualquier solicitud que pueda tener efectos duraderos. Verificar el encabezado HTTP Referrer también puede ayudar.

"Secuestro de JavaScript" es un tipo de ataque CSRF en el que una etiqueta <script> en el sitio de un atacante explota una página en el sitio de la víctima que devuelve información privada como JSON o JavaScript. Las posibles soluciones incluyen:

  • requerir un token de autenticación en los parámetros POST y GET para cualquier respuesta que devuelve información privada.

Confianza perdida en el cliente

Los desarrolladores de aplicaciones cliente-servidor deben reconocer que los clientes que no son de confianza pueden estar bajo el control de los atacantes. El autor de la aplicación no puede asumir que su código JavaScript se ejecutará según lo previsto (o en absoluto) porque un adversario determinado podría extraer cualquier secreto incrustado en el código. Algunas implicaciones son:

  • Los autores del sitio web no pueden ocultar perfectamente cómo funciona su JavaScript porque el código fuente cruda debe ser enviado al cliente. El código puede ser obfuscado, pero la obfuscación puede ser invertida.
  • La validación de formularios de JavaScript sólo proporciona comodidad para los usuarios, no seguridad. Si un sitio verifica que el usuario accedió a sus términos de servicio, o filtra caracteres inválidos fuera de campos que sólo deben contener números, debe hacerlo en el servidor, no sólo el cliente.
  • Los scripts pueden ser deshabilitados selectivamente, por lo que no se puede confiar en JavaScript para evitar operaciones como el clic derecho en una imagen para guardarla.
  • Se considera muy mala práctica incrustar información confidencial como contraseñas en JavaScript porque puede ser extraída por un atacante.

Confianza indebida en los desarrolladores

Los sistemas de administración de paquetes como npm y Bower son populares entre los desarrolladores de JavaScript. Dichos sistemas permiten que un desarrollador administre fácilmente las dependencias de su programa con respecto a otros desarrolladores. bibliotecas de programas. Los desarrolladores confían en que los mantenedores de las bibliotecas las mantendrán seguras y actualizadas, pero no siempre es así. Ha surgido una vulnerabilidad debido a esta confianza ciega. Las bibliotecas en las que se confía pueden tener nuevas versiones que provocan la aparición de errores o vulnerabilidades en todos los programas que dependen de las bibliotecas. A la inversa, una biblioteca puede quedar sin parches con vulnerabilidades conocidas en la naturaleza. En un estudio realizado con una muestra de 133 000 sitios web, los investigadores encontraron que el 37 % de los sitios web incluían una biblioteca con al menos una vulnerabilidad conocida. "La mediana de retraso entre la versión más antigua de la biblioteca utilizada en cada sitio web y la versión disponible más nueva de esa biblioteca es de 1177 días en ALEXA, y el desarrollo de algunas bibliotecas que todavía están en uso cesó hace años." Otra posibilidad es que el mantenedor de una biblioteca pueda eliminar la biblioteca por completo. Esto ocurrió en marzo de 2016 cuando Azer Koçulu eliminó su repositorio de npm. Esto provocó que se rompieran decenas de miles de programas y sitios web que dependían de sus bibliotecas.

Errores de codificación del navegador y complemento

JavaScript proporciona una interfaz para una amplia gama de capacidades del navegador, algunas de las cuales pueden tener fallas como desbordamientos de búfer. Estas fallas pueden permitir a los atacantes escribir scripts que ejecutarían cualquier código que deseen en el sistema del usuario. Este código no se limita de ninguna manera a otra aplicación de JavaScript. Por ejemplo, una explotación de saturación de búfer puede permitir que un atacante obtenga acceso a la API del sistema operativo con privilegios de superusuario.

Estas fallas han afectado a los principales navegadores, incluidos Firefox, Internet Explorer y Safari.

Los complementos, como los reproductores de video, Adobe Flash y la amplia gama de controles ActiveX habilitados de forma predeterminada en Microsoft Internet Explorer, también pueden tener fallas que se pueden explotar a través de JavaScript (tales fallas se han explotado en el pasado).

En Windows Vista, Microsoft ha intentado contener los riesgos de errores como desbordamientos de búfer ejecutando el proceso de Internet Explorer con privilegios limitados. De manera similar, Google Chrome limita sus renderizadores de página a su propio "sandbox".

Errores de implementación de Sandbox

Los navegadores web pueden ejecutar JavaScript fuera de la zona de pruebas, con los privilegios necesarios para, por ejemplo, crear o eliminar archivos. Dichos privilegios no están destinados a otorgarse al código de la Web.

La concesión incorrecta de privilegios a JavaScript desde la Web ha influido en las vulnerabilidades tanto de Internet Explorer como de Firefox. En Windows XP Service Pack 2, Microsoft degradó los privilegios de JScript en Internet Explorer.

Microsoft Windows permite que los archivos de código fuente de JavaScript en el disco duro de una computadora se inicien como programas de propósito general que no están en la zona de pruebas (consulte: Windows Script Host). Esto hace que JavaScript (como VBScript) sea un vector teóricamente viable para un caballo de Troya, aunque los caballos de Troya de JavaScript son poco comunes en la práctica.

Vulnerabilidades de hardware

En 2015, investigadores de seguridad describieron en un artículo una implementación de prueba de concepto basada en JavaScript de un ataque de martillo de fila.

En 2017, se demostró un ataque basado en JavaScript a través del navegador que podía eludir ASLR. Se llama "ASLR⊕Cache" o AnC.

En 2018, el documento que anunció los ataques de Spectre contra la ejecución especulativa en Intel y otros procesadores incluía una implementación de JavaScript.

Herramientas de desarrollo

Herramientas importantes han evolucionado con el lenguaje.

  • Cada navegador web principal tiene herramientas de desarrollo web incorporadas, incluyendo un depurador de JavaScript.
  • Herramientas estadísticas de análisis de programas, como ESLint y JSLint, escanean código JavaScript para ajustarse a un conjunto de normas y directrices.
  • Algunos navegadores tienen perfiles incorporados. También se han creado bibliotecas independientes de perfiles, como benchmark.js y jsbench.
  • Muchos editores de texto tienen compatibilidad sintaxis para resaltar el código JavaScript.

Tecnologías relacionadas

Java

Un concepto erróneo común es que JavaScript es lo mismo que Java. De hecho, ambos tienen una sintaxis similar a C (siendo el lenguaje C su lenguaje antecesor común más inmediato). Por lo general, también están en un espacio aislado (cuando se usan dentro de un navegador) y JavaScript se diseñó teniendo en cuenta la sintaxis y la biblioteca estándar de Java. En particular, todas las palabras clave de Java se reservaron en JavaScript original, la biblioteca estándar de JavaScript sigue las convenciones de nomenclatura de Java y Matemáticas y Date Los objetos se basan en clases de Java 1.0.

Java y JavaScript aparecieron por primera vez en 1995, pero Java fue desarrollado por James Gosling de Sun Microsystems y JavaScript por Brendan Eich de Netscape Communications.

Las diferencias entre los dos idiomas son más prominentes que sus similitudes. Java tiene escritura estática, mientras que la escritura de JavaScript es dinámica. Java se carga desde el código de bytes compilado, mientras que JavaScript se carga como código fuente legible por humanos. Los objetos de Java se basan en clases, mientras que los de JavaScript se basan en prototipos. Finalmente, Java no admitió la programación funcional hasta Java 8, mientras que JavaScript lo ha hecho desde el principio, influenciado por Scheme.

JSON

JSON, o notación de objetos de JavaScript, es un formato de intercambio de datos de propósito general que se define como un subconjunto de la sintaxis literal de objetos de JavaScript.

Mecanografiado

TypeScript (TS) es una variante estrictamente tipada de JavaScript. TS difiere al introducir anotaciones de tipos en variables y funciones, y al introducir un lenguaje de tipos para describir los tipos dentro de JS. De lo contrario, TS comparte prácticamente el mismo conjunto de características que JS, para permitir que se pueda transpilar fácilmente a JS para ejecutarlo en el lado del cliente e interoperar con otro código JS.

Ensamblaje web

Desde 2017, los navegadores web son compatibles con WebAssembly, un formato binario que permite que un motor de JavaScript ejecute partes críticas de rendimiento de secuencias de comandos de páginas web cercanas a la velocidad nativa. El código WebAssembly se ejecuta en el mismo espacio aislado que el código JavaScript normal.

asm.js es un subconjunto de JavaScript que sirvió como precursor de WebAssembly.

Transpiladores

JavaScript es el lenguaje dominante del lado del cliente de la Web, y muchos sitios web tienen muchos scripts. Así, se han creado transpiladores para convertir código escrito en otros lenguajes, lo que puede ayudar al proceso de desarrollo.

Contenido relacionado

Telecomunicaciones en las Islas Cook

Como la mayoría de los países y territorios de Oceanía, las telecomunicaciones en las Islas Cook están limitadas por su aislamiento y baja población, con...

Baño maría

Un baño maría un tipo de baño calentado, es un equipo utilizado en ciencia, industria y cocina para calentar materiales suavemente o para mantenerlos...

Tablero de mensajes

El MessagePad es una serie discontinuada de dispositivos de asistencia digital personal desarrollados por Apple Computer para la plataforma Newton en 1993....
Más resultados...
Tamaño del texto:
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save