JavaScript se diseñó en diez días, se le puso el nombre de otro lenguaje por marketing, y hoy es el único que ejecutan todos los navegadores del mundo. Es el caso más claro de que la suerte de una tecnología no depende solo de su calidad — y también de que un lenguaje puede mejorar muchísimo sin poder romper nada.
🎯 Por qué está en este programa
JavaScript es uno de los diez lenguajes del núcleo, y es el representante de la familia web (Atlas) junto con TypeScript.
Aporta al programa tres conceptos que ningún otro del núcleo enseña igual: la herencia por prototipos en vez de por clases (clase 112), el bucle de eventos con un solo hilo (clase 134) y la coerción débil de tipos, que es el mejor ejemplo posible de por qué la igualdad es un tema (clase 100).
| Año | 1995; ES5 en 2009; ES6/ES2015, el punto de inflexión; anual desde entonces |
| Autoría | Brendan Eich, Netscape — el prototipo, en diez días |
| Familia | JavaScript / web; sintaxis de C, semántica de Scheme y Self |
| Paradigma | Multiparadigma: funcional, orientado a objetos por prototipos, imperativo |
| Tipado | Dinámico y débil: las conversiones implícitas son parte del diseño |
| Memoria | Automática, con recolector generacional |
| Ejecución | JIT (V8, SpiderMonkey, JavaScriptCore); también AOT en algunos entornos |
| Estado | 🟢 Ubicuo — navegador, servidor, escritorio, móvil y sistemas embebidos |
En 1995, Netscape quería un lenguaje de guion para su navegador. Contrató a Brendan Eich con el encargo de que se pareciera a Java —que era lo que estaba de moda— y le dio diez días para el prototipo.
Eich quería hacer un Scheme para el navegador. El resultado fue un compromiso que explica casi todas las rarezas del lenguaje: funciones de primera clase y cierres de Scheme, herencia por prototipos de Self, y sintaxis de llaves de Java. Se llamó primero Mocha, luego LiveScript, y finalmente JavaScript por un acuerdo comercial con Sun — un nombre que ha causado confusión durante treinta años, porque Java y JavaScript no tienen relación.
Microsoft respondió con JScript, y de ahí nació la estandarización en ECMA — de donde viene el nombre feo pero correcto: ECMAScript.
Los años de ES3 a ES5 (1999-2009) fueron de estancamiento: ES4 se abandonó tras una guerra política, y el lenguaje se quedó congelado mientras la web crecía. Lo que sí ocurrió en esa década fue jQuery —que tapó las diferencias entre navegadores— y V8 (2008), el motor de Chrome con JIT que multiplicó por cien el rendimiento y cambió lo que se podía hacer con el lenguaje.
Node.js (2009) sacó JavaScript del navegador usando V8, y ES2015 (ES6) lo modernizó de golpe:
let/const, clases, módulos, promesas, funciones flecha, desestructuración, plantillas de cadena.
Desde entonces hay una versión anual, y el lenguaje ha crecido con async/await, opcional
encadenado, BigInt y el emparejamiento de patrones en camino.
Uno, los prototipos (clase 112). En JavaScript no hay clases de verdad: class es azúcar
sobre un mecanismo donde cada objeto tiene un enlace a otro objeto, y la búsqueda de una propiedad
sube por esa cadena. Es más simple y más flexible que las clases, y es el modelo que
Self inventó.
Dos, el bucle de eventos (clases 134 y 161). JavaScript tiene un solo hilo, y toda la
concurrencia es asíncrona: la operación se registra y se sigue; cuando termina, el bucle ejecuta la
retrollamada. Es el mismo modelo que Tcl tenía en 1993 con fileevent, y es lo que permite
atender decenas de miles de conexiones sin un hilo por cada una.
Y tres, la coerción débil, que es el ejemplo didáctico perfecto de la clase 100:
0 == "0" // true
0 == [] // true
"0" == [] // false ← la igualdad NO es transitiva
[] + {} // "[object Object]"
0.1 + 0.2 // 0.30000000000000004 (clase 073: esto pasa en TODOS)
Y aquí conviene ser justo. La última línea no es un defecto de JavaScript: es IEEE 754, y ocurre igual en Python, Java y C (clase 073). Las anteriores sí lo son, y la respuesta del ecosistema fue clara: usar siempre
===, que no convierte. Es exactamente el patrón de la clase 146 — una regla de estilo que corrige una decisión del lenguaje y que los analizadores hacen cumplir.
var a let/const, que arregla el alcance por función y el hoisting (clase 087).async/await sobre promesas: código asíncrono con aspecto secuencial (clase 134).BigInt para enteros de precisión arbitraria, y Temporal para fechas —la corrección de la
peor API de la biblioteca estándar—.node main.mjs < entrada.txt # el comando de la clase 041
deno run --allow-read main.mjs # con permisos EXPLÍCITOS
bun run main.mjs
npx eslint . && npx prettier --check . # calidad (clase 146)
node --test # pruebas, en el propio Node
import { readFileSync } from "node:fs";
// Números en JS: un solo tipo `number` (doble de 64 bits) para todo.
const [precio, cantidad, descuento] = readFileSync(0, "utf8")
.trim()
.split(/\s+/)
.map(Number);
const subtotal = precio * cantidad;
const total = subtotal * (1 - descuento);
console.log(`Total: ${total.toFixed(2)}`);
Lo que hay que ver.
int: cantidad es un doble de 64 bits, igual que el
precio. Eso simplifica el lenguaje y trae la consecuencia de la clase 045: los enteros por encima
de 2⁵³ pierden precisión, que es la razón de que las APIs envíen los identificadores grandes como
cadenas (clase 159).const no significa constante: significa que el nombre no se reasigna. Un objeto declarado
con const sigue siendo mutable — una distinción que la clase 102 desarrolla..trim().split().map() es el estilo funcional del lenguaje, heredado de Scheme y
popularizado por las bibliotecas.readFileSync(0, ...) lee el descriptor 0, que es la entrada estándar: Node no tiene una
lectura de línea síncrona sencilla, y este es el idioma habitual.this y prototipos.=== y el modo estricto.⏮️ Volver al Atlas · 🗂️ Todas las fichas · 🔗 Relacionadas: TypeScript · Dart · Elm · ActionScript · Lua