JavaScript — язык программирования, который стал основой для целого класса гибридных мобильных технологий. React Native, Ionic, Apache Cordova и многие другие фреймворки позволяют создавать мобильные приложения на JS, используя единый стек технологий с веб-разработкой. При этом JavaScript остаётся самым используемым языком программирования десятый год подряд по данным опроса Stack Overflow (2025). Подробнее смотрите в результатах опроса Stack Overflow.
Главное
JavaScript (JS) — язык программирования высокого уровня с динамической типизацией, прототипным наследованием и функциями как объектами первого класса. Создан Бренданом Эйхом в 1995 году за 10 дней. Является одним из трёх основных языков веб-технологий (HTML, CSS, JS) и основой для серверной платформы Node.js (2009), которая позволила JS выйти за пределы браузера.
В мобильной разработке JavaScript используется в трёх парадигмах: нативная компиляция (React Native с Hermes/JSC), WebView-контейнеры (Ionic, Cordova) и серверный JS (Node.js + Express для бэкенда мобильных приложений). React Native — доминирующая технология: по данным Statista (2025), 38% кроссплатформенных проектов используют React Native, уступая только Flutter (46%).
Ключевая особенность JavaScript — однопоточная модель выполнения с неблокирующим вводом-выводом. Event loop позволяет обрабатывать тысячи асинхронных операций в одном потоке без создания потоков ОС. Это делает JS эффективным для I/O-нагруженных приложений (сетевые запросы, работа с БД), но требует осторожности при CPU-интенсивных вычислениях.
Стандарт ECMAScript (ES) определяет спецификацию JavaScript. ES6 (2015) ввёл let/const, стрелочные функции, классы, модули, Promise. ES2020 — Optional Chaining (?.), Nullish Coalescing (??). ES2023 — Array findLast, Hashbang Grammar. Современные движки Hermes (React Native) и V8 (Node.js) поддерживают ES2022+. React Native Hermes поддерживает ES2020+ с отдельными ограничениями на Proxy и Symbol.
| Версия ES | Год | Ключевые фичи | Поддержка RN |
|---|---|---|---|
| ES6 | 2015 | let/const, Promise, class, modules, arrow functions | Полная |
| ES8 | 2017 | async/await, Object.entries | Полная |
| ES2020 | 2020 | Optional Chaining, Nullish Coalescing, BigInt | Полная |
| ES2022 | 2022 | Top-level await, .at(), Error Cause | Hermes ограничена |
Синтаксис JavaScript — C-подобный, динамически типизированный. Тип переменной определяется значением и может меняться в рантайме. let и const (ES6) заменили var для блочной области видимости. Примитивные типы: string, number, boolean, null, undefined, symbol, bigint. Всё остальное — объект (object, array, function, date, regexp).
JavaScript — язык с функциями высшего порядка. Функции можно присваивать переменным, передавать как аргументы, возвращать из других функций. Стрелочные функции (=>) не имеют собственного this — они наследуют this от внешнего контекста. Замыкание (closure) — функция, запоминающая переменные из области видимости, где она была создана.
// Типы данных и функции в JavaScript
// Примитивные типы
const name = 'React Native';
let version = 0.71;
var isActive = true; // устаревший var
// Объекты и массивы
const app = {
platform: 'iOS',
version: 15,
getInfo() {
return `${this.platform} ${this.version}`;
}
};
const items = ['Dart', 'Kotlin', 'Swift'];
// Функция высшего порядка
function filterByVersion(apps, minVersion) {
return apps.filter(app => app.version >= minVersion);
}
// Замыкание (closure)
function createCounter() {
let count = 0;
return function() {
return ++count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
// Spread оператор для копирования объектов
const newApp = { ...app, version: 16 };Spread оператор ... создаёт поверхностную копию объекта. Деструктуризация (const { platform, version } = app) извлекает поля в переменные. Стрелочная функция в filterByVersion пишется короче, чем function-выражение, и не создаёт собственный this — это критично в React Native компонентах, где this ссылается на класс компонента.
JavaScript использует прототипное наследование, а не классовое как Java или C#. Классы (ES6) — синтаксический сахар поверх прототипов. Каждый объект имеет внутреннюю ссылку [[Prototype]] на другой объект. При обращении к свойству, которого нет в объекте, JS ищет его в цепочке прототипов. Классовый синтаксис (extends, super) делает код читаемее, но под капотом остаются прототипы.
// Классы в JavaScript — синтаксический сахар
class PlatformService {
// Приватное поле (ES2022)
#apiKey;
constructor(name, apiKey) {
this.name = name;
this.#apiKey = apiKey;
}
// Статический метод
static getPlatforms() {
return ['iOS', 'Android'];
}
// Геттер
get info() {
return `${this.name} SDK`;
}
// Асинхронный метод
async initialize() {
return await this.#validateKey();
}
#validateKey() {
return this.#apiKey.length > 10;
}
}
// Наследование
class AndroidService extends PlatformService {
constructor(apiKey) {
super('Android', apiKey);
}
}Приватные поля #apiKey (ES2022) обеспечивают настоящую инкапсуляцию, недоступную с _underscore-соглашениями. Статический метод getPlatforms принадлежит классу, а не экземпляру. Геттер info вычисляется при обращении. async/await делает асинхронный код линейным. React Native Hermes поддерживает приватные поля с версии 0.71.
Асинхронность JavaScript основана на event loop — бесконечном цикле, который проверяет стек вызовов (call stack) и очереди задач. Call stack — синхронный код, microtask queue — Promise.then/catch/finally, macrotask queue — setTimeout, setInterval, I/O. Event loop берёт задачи из microtask сначала, затем из macrotask. Блокировка call stack (бесконечный цикл) останавливает весь UI.
Promise — объект, представляющий будущее значение. Промис может быть pending (ожидание), fulfilled (успех), rejected (ошибка). Цепочка .then().catch().finally() обрабатывает асинхронный результат. async/await (ES8) — синтаксический сахар: функция async возвращает Promise, await приостанавливает выполнение до разрешения промиса, не блокируя поток.
// Асинхронная загрузка данных в 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('Fetch failed:', error);
setLoading(false);
}
}
}
fetchUser();
return () => { cancelled = true; };
}, [userId]);
if (loading) return <ActivityIndicator />;
return (
<View>
<Text>{user?.name ?? 'Unknown'}</Text>
</View>
);
}Хук useEffect с async-функцией fetchUser выполняет HTTP-запрос при монтировании компонента. Флаг cancelled предотвращает setState после размонтирования — распространённая проблема React Native. Optional Chaining user?.name и Nullish Coalescing ?? обрабатывают undefined без ошибок. ActivityIndicator отображается во время загрузки — асинхронный паттерн, знакомый каждому JS-разработчику.
React Native — фреймворк от Meta (Facebook) для создания нативных мобильных приложений на JavaScript. В отличие от WebView-подхода, React Native рендерит настоящие нативные компоненты (UIView для iOS, ViewGroup для Android). JS-код выполняется в отдельном потоке (Hermes или JSC) и общается с нативным UI-потоком через Bridge (старая архитектура) или JSI (новая архитектура Fabric).
React Native состоит из JS-потока (ваш код), нативного потока (UI) и Bridge/JSI для их взаимодействия. В старой архитектуре (Bridge) JSON-сообщения сериализуются и передаются асинхронно — это создаёт задержки при быстрых анимациях. Новая архитектура Fabric (React Native 0.68+) использует JSI (JavaScript Interface) — прямое взаимодействие JS с C++ объектами без сериализации.
// React Native компонент с нативным API
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>
);
}Компонент LocationTracker демонстрирует работу с нативным API геолокации. Platform.OS различает Android и iOS. PermissionsAndroid.request — нативный диалог разрешений Android. Geolocation.getCurrentPosition — модуль @react-native-community/geolocation, подключаемый через npm. React Native предоставляет JS-интерфейсы для камеры, Bluetooth, акселерометра и других датчиков.
Ionic — фреймворк для гибридных мобильных приложений, использующий WebView для рендеринга HTML/CSS/JS. В отличие от React Native, Ionic не создаёт нативные компоненты — приложение работает внутри веб-контейнера (WebView) на iOS (WKWebView) и Android (Android WebView). Это даёт 100% повторное использование веб-кода, но ограничивает производительность сложных анимаций.
Apache Cordova — основа Ionic, обеспечивающая доступ к нативным API через JavaScript-плагины. Камера, GPS, контакты, файловая система — всё доступно через cordova-plugin-*. Ionic 7+ использует Capacitor — преемник Cordova с лучшей производительностью, поддержкой ESM и прямым доступом к iOS/Android SDK через Swift и Kotlin.
| Характеристика | React Native | Ionic (Capacitor) | Cordova |
|---|---|---|---|
| Рендеринг UI | Нативные компоненты | WebView (WKWebView) | WebView |
| Язык | JS/TS | JS/TS + HTML/CSS | JS/TS + HTML/CSS |
| Нативные API | Bridge/JSI + модули | Capacitor Plugins | Cordova Plugins |
| Производительность | Высокая (60 FPS) | Средняя (зависит от WebView) | Средняя |
| Размер APK | ~25-40 МБ | ~10-15 МБ | ~8-12 МБ |
| Повторное использование | ~60% кода | ~95% кода с веб-версией | ~95% |
Инструменты JS-разработчика для мобильных приложений включают Node.js, npm/yarn, Expo, React Native CLI и Metro bundler. Node.js — среда выполнения JS вне браузера, основа экосистемы. npm (Node Package Manager) — менеджер пакетов с 2+ миллионами библиотек. npx — утилита для запуска npm-пакетов без установки.
Expo — надстройка над React Native, упрощающая разработку: не требует Xcode/Android Studio для начала, предоставляет Managed Workflow с предустановленными библиотеками. Expo Application Services (EAS) — сборка и публикация в облаке. Metro — бандлер React Native, собирающий JS-код и зависимости в один файл. Hermes — JS-движок от Meta, оптимизированный для мобильных устройств с AOT-компиляцией.
// package.json — конфигурация 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"
}
}Файл package.json — основа любого JS-проекта. Скрипты start, android, ios запускают Metro бандлер и сборку. Зависимости разделены на dependencies (рантайм) и devDependencies (тесты, линтеры). React Navigation — стандартный роутер. Jest — фреймворк для тестирования. ESLint — статический анализатор, проверяющий стиль кода и потенциальные ошибки.
Часто задаваемые вопросы
JavaScript (JS) — язык программирования с динамической типизацией, прототипным наследованием и однопоточной event loop моделью. Создан в 1995 году. В мобильной разработке используется через React Native (нативные компоненты + JS-логика) и Ionic (WebView-контейнер). Является самым используемым языком десятый год подряд по данным Stack Overflow.
React Native выполняет JS в отдельном потоке (Hermes или JSC). JS-поток управляет логикой и состоянием, нативный поток рендерит UI-компоненты. Обмен данными — через Bridge (старая архитектура, JSON-сериализация) или JSI (новая архитектура Fabric, прямой C++ доступ). Hermes — JS-движок от Meta с AOT-компиляцией, уменьшающий время запуска на 50%.
JavaScript — динамически типизированный, типы проверяются в рантайме. TypeScript добавляет статическую типизацию с проверкой на этапе компиляции, интерфейсы, дженерики и перечисления. Любой JS-код валиден в TypeScript. TS компилируется (транспилируется) в чистый JS через tsc или Babel. В React Native TS используется в ~65% новых проектов.
Основные: React Native (Meta) — нативная рендеринг-платформа с Bridge/Fabric. Ionic (Capacitor) — WebView-контейнер с доступом к нативным API через плагины. Apache Cordova — предшественник Ionic, также WebView. NativeScript — прямой доступ к нативным API без WebView. Expo — надстройка над React Native для быстрого прототипирования без нативной сборки.
Асинхронность JS основана на event loop: call stack (синхронный код) → microtask queue (Promise.then) → macrotask queue (setTimeout, I/O). Promise — объект для асинхронных операций. async/await — синтаксический сахар над Promise. Однопоточная модель не блокирует UI, но CPU-интенсивные задачи требуют Web Workers или отдельного потока (в React Native — InteractionManager).
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.