JavaScript es un lenguaje de programación que se convirtió en la base de toda una clase de tecnologías móviles híbridas. React Native, Ionic, Apache Cordova y muchos otros frameworks permiten crear aplicaciones móviles en JS utilizando un stack tecnológico unificado con el desarrollo web. Al mismo tiempo, JavaScript sigue siendo el lenguaje de programación más utilizado por décimo año consecutivo según la encuesta de Stack Overflow (2025). Más detalles en los resultados de la encuesta de Stack Overflow.
Puntos clave
JavaScript (JS) es un lenguaje de programación de alto nivel con tipado dinámico, herencia prototípica y funciones como objetos de primera clase. Fue creado por Brendan Eich en 1995 en 10 días. Es uno de los tres lenguajes principales de las tecnologías web (HTML, CSS, JS) y la base de la plataforma del lado del servidor Node.js (2009), que permitió a JS salir del navegador.
En el desarrollo móvil, JavaScript se utiliza en tres paradigmas: compilación nativa (React Native con Hermes/JSC), contenedores WebView (Ionic, Cordova) y JS del lado del servidor (Node.js + Express para backend de aplicaciones móviles). React Native es la tecnología dominante: según Statista (2025), el 38% de los proyectos multiplataforma usan React Native, solo superado por Flutter (46%).
La característica clave de JavaScript es el modelo de ejecución de un solo hilo con E/S no bloqueante. El event loop permite procesar miles de operaciones asíncronas en un solo hilo sin crear hilos del SO. Esto hace que JS sea eficiente para aplicaciones con uso intensivo de E/S (solicitudes de red, operaciones de base de datos), pero requiere precaución con cálculos intensivos de CPU.
El estándar ECMAScript (ES) define la especificación de JavaScript. ES6 (2015) introdujo let/const, funciones flecha, clases, módulos, Promise. ES2020 — Optional Chaining (?.), Nullish Coalescing (??). ES2023 — Array findLast, Hashbang Grammar. Los motores modernos Hermes (React Native) y V8 (Node.js) soportan ES2022+. React Native Hermes soporta ES2020+ con ciertas limitaciones en Proxy y Symbol.
| Versión ES | Año | Características clave | Soporte RN |
|---|---|---|---|
| ES6 | 2015 | let/const, Promise, class, modules, arrow functions | Completo |
| ES8 | 2017 | async/await, Object.entries | Completo |
| ES2020 | 2020 | Optional Chaining, Nullish Coalescing, BigInt | Completo |
| ES2022 | 2022 | Top-level await, .at(), Error Cause | Hermes limitado |
La sintaxis de JavaScript es similar a C, con tipado dinámico. El tipo de la variable se determina por el valor y puede cambiar en tiempo de ejecución. let y const (ES6) reemplazaron a var para el ámbito de bloque. Tipos primitivos: string, number, boolean, null, undefined, symbol, bigint. Todo lo demás es un objeto (object, array, function, date, regexp).
JavaScript es un lenguaje con funciones de orden superior. Las funciones pueden asignarse a variables, pasarse como argumentos, devolverse desde otras funciones. Las funciones flecha (=>) no tienen su propio this — heredan this del contexto externo. Un closure es una función que recuerda las variables del ámbito donde fue creada.
// Tipos de datos y funciones en JavaScript
// Tipos primitivos
const name = 'React Native';
let version = 0.71;
var isActive = true; // var obsoleto
// Objetos y arrays
const app = {
platform: 'iOS',
version: 15,
getInfo() {
return `${this.platform} ${this.version}`;
}
};
const items = ['Dart', 'Kotlin', 'Swift'];
// Función de orden superior
function filterByVersion(apps, minVersion) {
return apps.filter(app => app.version >= minVersion);
}
// Clausura (closure)
function createCounter() {
let count = 0;
return function() {
return ++count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
// Operador spread para copiar objetos
const newApp = { ...app, version: 16 };El operador spread ... crea una copia superficial de un objeto. La desestructuración (const { platform, version } = app) extrae campos en variables. La función flecha en filterByVersion es más corta que una expresión function y no crea su propio this — esto es crítico en componentes de React Native donde this se refiere a la clase del componente.
JavaScript usa herencia prototípica, no clásica como Java o C#. Las clases (ES6) son azúcar sintáctico sobre prototipos. Cada objeto tiene una referencia interna [[Prototype]] a otro objeto. Al acceder a una propiedad que no existe en el objeto, JS la busca en la cadena de prototipos. La sintaxis de clases (extends, super) hace el código más legible, pero internamente siguen siendo prototipos.
// Clases en JavaScript — azúcar sintáctico
class PlatformService {
// Campo privado (ES2022)
#apiKey;
constructor(name, apiKey) {
this.name = name;
this.#apiKey = apiKey;
}
// Método estático
static getPlatforms() {
return ['iOS', 'Android'];
}
// Getter
get info() {
return `${this.name} SDK`;
}
// Método asíncrono
async initialize() {
return await this.#validateKey();
}
#validateKey() {
return this.#apiKey.length > 10;
}
}
// Herencia
class AndroidService extends PlatformService {
constructor(apiKey) {
super('Android', apiKey);
}
}Los campos privados #apiKey (ES2022) proporcionan encapsulación real, inaccesible con convenciones de _. El método estático getPlatforms pertenece a la clase, no a la instancia. El getter info se calcula al acceder. async/await hace que el código asíncrono sea lineal. React Native Hermes soporta campos privados desde la versión 0.71.
La asincronía de JavaScript se basa en el event loop — un bucle infinito que verifica la pila de llamadas (call stack) y las colas de tareas. El call stack maneja código síncrono, la microtask queue maneja Promise.then/catch/finally, la macrotask queue maneja setTimeout, setInterval, E/S. El event loop toma primero las tareas de microtask, luego de macrotask. Bloquear el call stack (bucle infinito) detiene toda la UI.
Promise es un objeto que representa un valor futuro. Una promesa puede estar pending (pendiente), fulfilled (cumplida) o rejected (rechazada). La cadena .then().catch().finally() maneja el resultado asíncrono. async/await (ES8) es azúcar sintáctico: una función async devuelve una Promise, await pausa la ejecución hasta que la promesa se resuelve sin bloquear el hilo.
// Carga asíncrona de datos en React Native
import React, { useState, useEffect } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
async function fetchUser() {
try {
const response = await fetch(
`https://api.example.com/users/${userId}`
);
if (!response.ok) {
throw new Error('Network error');
}
const data = await response.json();
if (!cancelled) {
setUser(data);
setLoading(false);
}
} catch (error) {
if (!cancelled) {
console.error('Error de fetch:', error);
setLoading(false);
}
}
}
fetchUser();
return () => { cancelled = true; };
}, [userId]);
if (loading) return <ActivityIndicator />;
return (
<View>
<Text>{user?.name ?? 'Unknown'}</Text>
</View>
);
}El hook useEffect con la función async fetchUser realiza una solicitud HTTP al montar el componente. El flag cancelled evita setState después del desmontaje — un problema común en React Native. Optional Chaining user?.name y Nullish Coalescing ?? manejan undefined sin errores. ActivityIndicator se muestra durante la carga — un patrón asíncrono familiar para todo desarrollador JS.
React Native es un framework de Meta (Facebook) para crear aplicaciones móviles nativas en JavaScript. A diferencia del enfoque WebView, React Native renderiza componentes nativos reales (UIView para iOS, ViewGroup para Android). El código JS se ejecuta en un hilo separado (Hermes o JSC) y se comunica con el hilo nativo de UI a través de Bridge (arquitectura antigua) o JSI (nueva arquitectura Fabric).
React Native consta del hilo JS (tu código), el hilo nativo (UI) y Bridge/JSI para su interacción. En la arquitectura antigua (Bridge), los mensajes JSON se serializan y transmiten de forma asíncrona — esto crea retrasos durante animaciones rápidas. La nueva arquitectura Fabric (React Native 0.68+) usa JSI (JavaScript Interface) — interacción directa de JS con objetos C++ sin serialización.
// Componente React Native con API nativa
import React, { useState, useEffect } from 'react';
import {
View, Text, TouchableOpacity, Platform,
PermissionsAndroid, Alert
} from 'react-native';
import Geolocation from '@react-native-community/geolocation';
function LocationTracker() {
const [location, setLocation] = useState(null);
useEffect(() => {
requestLocationPermission();
}, []);
async function requestLocationPermission() {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
);
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
Alert.alert('Permission denied');
return;
}
}
getCurrentPosition();
}
function getCurrentPosition() {
Geolocation.getCurrentPosition(
pos => setLocation({
lat: pos.coords.latitude,
lng: pos.coords.longitude
}),
error => Alert.alert('Error', error.message),
{ enableHighAccuracy: true, timeout: 15000 }
);
}
return (
<View>
<Text>Lat: {location?.lat ?? 'N/A'}</Text>
<Text>Lng: {location?.lng ?? 'N/A'}</Text>
<TouchableOpacity onPress={getCurrentPosition}>
<Text>Update Location</Text>
</TouchableOpacity>
</View>
);
}El componente LocationTracker demuestra el trabajo con la API nativa de geolocalización. Platform.OS distingue entre Android e iOS. PermissionsAndroid.request es el diálogo nativo de permisos de Android. Geolocation.getCurrentPosition — un módulo de @react-native-community/geolocation, instalado vía npm. React Native proporciona interfaces JS para la cámara, Bluetooth, acelerómetro y otros sensores.
Ionic es un framework para aplicaciones móviles híbridas que usa WebView para renderizar HTML/CSS/JS. A diferencia de React Native, Ionic no crea componentes nativos — la aplicación se ejecuta dentro de un contenedor web (WebView) en iOS (WKWebView) y Android (Android WebView). Esto proporciona un 100% de reutilización del código web pero limita el rendimiento de animaciones complejas.
Apache Cordova es la base de Ionic, que proporciona acceso a APIs nativas mediante plugins de JavaScript. Cámara, GPS, contactos, sistema de archivos — todo está disponible a través de cordova-plugin-*. Ionic 7+ usa Capacitor — el sucesor de Cordova con mejor rendimiento, soporte de ESM y acceso directo al SDK de iOS/Android a través de Swift y Kotlin.
| Característica | React Native | Ionic (Capacitor) | Cordova |
|---|---|---|---|
| Renderizado UI | Componentes nativos | WebView (WKWebView) | WebView |
| Lenguaje | JS/TS | JS/TS + HTML/CSS | JS/TS + HTML/CSS |
| APIs nativas | Bridge/JSI + módulos | Capacitor Plugins | Cordova Plugins |
| Rendimiento | Alto (60 FPS) | Medio (depende del WebView) | Medio |
| Tamaño APK | ~25-40 MB | ~10-15 MB | ~8-12 MB |
| Reutilización | ~60% código | ~95% código con versión web | ~95% |
Las herramientas del desarrollador JS para aplicaciones móviles incluyen Node.js, npm/yarn, Expo, React Native CLI y Metro bundler. Node.js es un entorno de ejecución de JS fuera del navegador, la base del ecosistema. npm (Node Package Manager) es un gestor de paquetes con más de 2 millones de librerías. npx es una utilidad para ejecutar paquetes npm sin instalación.
Expo es una capa sobre React Native que simplifica el desarrollo: no requiere Xcode/Android Studio para empezar, proporciona Managed Workflow con librerías preinstaladas. Expo Application Services (EAS) — compilación y publicación en la nube. Metro es el bundler de React Native que ensambla el código JS y las dependencias en un solo archivo. Hermes es un motor JS de Meta optimizado para dispositivos móviles con compilación AOT.
// package.json — configuración del proyecto React Native
{
"name": "MyMobileApp",
"version": "1.0.0",
"scripts": {
"start": "npx react-native start",
"android": "npx react-native run-android",
"ios": "npx react-native run-ios",
"test": "jest",
"lint": "eslint . --ext .ts,.tsx"
},
"dependencies": {
"react": "^18.2.0",
"react-native": "^0.73.0",
"@react-navigation/native": "^6.1.0",
"@react-native-community/geolocation": "^3.2.0"
},
"devDependencies": {
"jest": "^29.7.0",
"eslint": "^8.56.0",
"metro-react-native-babel-preset": "^0.77.0"
}
}El archivo package.json es la base de cualquier proyecto JS. Los scripts start, android, ios lanzan el bundler Metro y la compilación. Las dependencias se dividen en dependencies (tiempo de ejecución) y devDependencies (tests, linters). React Navigation es el router estándar. Jest es un framework de pruebas. ESLint es un analizador estático que verifica el estilo del código y errores potenciales.
Preguntas frecuentes
JavaScript (JS) es un lenguaje de programación con tipado dinámico, herencia prototípica y modelo de event loop de un solo hilo. Creado en 1995. En el desarrollo móvil se usa a través de React Native (componentes nativos + lógica JS) e Ionic (contenedor WebView). Es el lenguaje más utilizado por décimo año consecutivo según datos de Stack Overflow.
React Native ejecuta JS en un hilo separado (Hermes o JSC). El hilo JS gestiona la lógica y el estado, el hilo nativo renderiza los componentes UI. El intercambio de datos se realiza a través de Bridge (arquitectura antigua, serialización JSON) o JSI (nueva arquitectura Fabric, acceso directo a C++). Hermes es un motor JS de Meta con compilación AOT que reduce el tiempo de inicio en un 50%.
JavaScript tiene tipado dinámico — los tipos se verifican en tiempo de ejecución. TypeScript añade tipado estático con verificación en tiempo de compilación, interfaces, genéricos y enumeraciones. Cualquier código JS es TypeScript válido. TS se compila (transpila) a JS puro mediante tsc o Babel. En React Native, TS se usa en ~65% de los proyectos nuevos.
Principales: React Native (Meta) — plataforma de renderizado nativo con Bridge/Fabric. Ionic (Capacitor) — contenedor WebView con acceso a APIs nativas mediante plugins. Apache Cordova — predecesor de Ionic, también WebView. NativeScript — acceso directo a APIs nativas sin WebView. Expo — capa sobre React Native para prototipado rápido sin configuración de compilación nativa.
La asincronía de JS se basa en el event loop: call stack (código síncrono) → microtask queue (Promise.then) → macrotask queue (setTimeout, E/S). Promise es un objeto para operaciones asíncronas. async/await es azúcar sintáctico sobre Promise. El modelo de un solo hilo no bloquea la UI, pero las tareas intensivas de CPU requieren Web Workers o un hilo separado (en React Native — InteractionManager).
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.