JavaScript là một ngôn ngữ lập trình đã trở thành nền tảng cho toàn bộ một lớp công nghệ di động lai. React Native, Ionic, Apache Cordova và nhiều framework khác cho phép tạo ứng dụng di động bằng JS sử dụng một ngăn xếp công nghệ thống nhất với phát triển web. Đồng thời, JavaScript vẫn là ngôn ngữ lập trình được sử dụng nhiều nhất trong năm thứ mười liên tiếp theo khảo sát Stack Overflow (2025). Xem chi tiết trong kết quả khảo sát Stack Overflow.
Những điểm chính
JavaScript (JS) là một ngôn ngữ lập trình cấp cao với kiểu động, kế thừa nguyên mẫu và hàm là đối tượng hạng nhất. Nó được tạo ra bởi Brendan Eich vào năm 1995 trong 10 ngày. Nó là một trong ba ngôn ngữ chính của công nghệ web (HTML, CSS, JS) và là nền tảng cho nền tảng máy chủ Node.js (2009), cho phép JS vượt ra ngoài trình duyệt.
Trong phát triển di động, JavaScript được sử dụng theo ba mô hình: biên dịch gốc (React Native với Hermes/JSC), vùng chứa WebView (Ionic, Cordova) và JS phía máy chủ (Node.js + Express cho backend ứng dụng di động). React Native là công nghệ thống trị: theo Statista (2025), 38% dự án đa nền tảng sử dụng React Native, chỉ sau Flutter (46%).
Đặc điểm chính của JavaScript là mô hình thực thi đơn luồng với I/O không chặn. Vòng lặp sự kiện cho phép xử lý hàng nghìn thao tác bất đồng bộ trong một luồng mà không cần tạo luồng hệ điều hành. Điều này làm cho JS hiệu quả cho các ứng dụng I/O nhiều (yêu cầu mạng, thao tác cơ sở dữ liệu), nhưng cần thận trọng với các tính toán tốn CPU.
Tiêu chuẩn ECMAScript (ES) định nghĩa đặc tả JavaScript. ES6 (2015) giới thiệu let/const, hàm mũi tên, lớp, mô-đun, Promise. ES2020 — Optional Chaining (?.), Nullish Coalescing (??). ES2023 — Array findLast, Hashbang Grammar. Các công cụ hiện đại Hermes (React Native) và V8 (Node.js) hỗ trợ ES2022+. React Native Hermes hỗ trợ ES2020+ với một số hạn chế trên Proxy và Symbol.
| Phiên bản ES | Năm | Tính năng chính | Hỗ trợ RN |
|---|---|---|---|
| ES6 | 2015 | let/const, Promise, class, modules, arrow functions | Đầy đủ |
| ES8 | 2017 | async/await, Object.entries | Đầy đủ |
| ES2020 | 2020 | Optional Chaining, Nullish Coalescing, BigInt | Đầy đủ |
| ES2022 | 2022 | Top-level await, .at(), Error Cause | Hermes hạn chế |
Cú pháp JavaScript giống C, kiểu động. Kiểu của biến được xác định bởi giá trị và có thể thay đổi trong thời gian chạy. let và const (ES6) đã thay thế var cho phạm vi khối. Các kiểu nguyên thủy: string, number, boolean, null, undefined, symbol, bigint. Mọi thứ khác đều là đối tượng (object, array, function, date, regexp).
JavaScript là một ngôn ngữ có hàm bậc cao. Hàm có thể được gán cho biến, truyền như đối số, trả về từ các hàm khác. Hàm mũi tên (=>) không có this riêng — chúng kế thừa this từ ngữ cảnh bên ngoài. Bao đóng (closure) là một hàm ghi nhớ các biến từ phạm vi nơi nó được tạo ra.
// Kiểu dữ liệu và hàm trong JavaScript
// Kiểu nguyên thủy
const name = 'React Native';
let version = 0.71;
var isActive = true; // var cũ
// Đối tượng và mảng
const app = {
platform: 'iOS',
version: 15,
getInfo() {
return `${this.platform} ${this.version}`;
}
};
const items = ['Dart', 'Kotlin', 'Swift'];
// Hàm bậc cao
function filterByVersion(apps, minVersion) {
return apps.filter(app => app.version >= minVersion);
}
// Bao đóng (closure)
function createCounter() {
let count = 0;
return function() {
return ++count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
// Toán tử spread để sao chép đối tượng
const newApp = { ...app, version: 16 };Toán tử spread ... tạo một bản sao nông của một đối tượng. Destructuring (const { platform, version } = app) trích xuất các trường thành biến. Hàm mũi tên trong filterByVersion ngắn hơn biểu thức function và không tạo this riêng — điều này rất quan trọng trong các thành phần React Native nơi this tham chiếu đến lớp thành phần.
JavaScript sử dụng kế thừa nguyên mẫu, không phải kế thừa lớp như Java hay C#. Lớp (ES6) là đường cú pháp trên các nguyên mẫu. Mỗi đối tượng có một tham chiếu [[Prototype]] nội bộ đến một đối tượng khác. Khi truy cập một thuộc tính không tồn tại trên đối tượng, JS sẽ tìm nó trong chuỗi nguyên mẫu. Cú pháp lớp (extends, super) làm cho mã dễ đọc hơn, nhưng bên dưới vẫn là các nguyên mẫu.
// Lớp trong JavaScript — đường cú pháp
class PlatformService {
// Trường riêng tư (ES2022)
#apiKey;
constructor(name, apiKey) {
this.name = name;
this.#apiKey = apiKey;
}
// Phương thức tĩnh
static getPlatforms() {
return ['iOS', 'Android'];
}
// Getter
get info() {
return `${this.name} SDK`;
}
// Phương thức bất đồng bộ
async initialize() {
return await this.#validateKey();
}
#validateKey() {
return this.#apiKey.length > 10;
}
}
// Kế thừa
class AndroidService extends PlatformService {
constructor(apiKey) {
super('Android', apiKey);
}
}Trường riêng tư #apiKey (ES2022) cung cấp đóng gói thực sự, không khả dụng với quy ước dấu gạch dưới _. Phương thức tĩnh getPlatforms thuộc về lớp, không phải phiên bản. Getter info được tính toán khi truy cập. async/await làm cho mã bất đồng bộ trở nên tuyến tính. React Native Hermes hỗ trợ trường riêng tư từ phiên bản 0.71.
Tính bất đồng bộ của JavaScript dựa trên vòng lặp sự kiện — một vòng lặp vô hạn kiểm tra ngăn xếp cuộc gọi (call stack) và hàng đợi tác vụ. Call stack xử lý mã đồng bộ, microtask queue xử lý Promise.then/catch/finally, macrotask queue xử lý setTimeout, setInterval, I/O. Vòng lặp sự kiện lấy tác vụ từ microtask trước, sau đó từ macrotask. Chặn call stack (vòng lặp vô hạn) sẽ dừng toàn bộ UI.
Promise là một đối tượng đại diện cho một giá trị trong tương lai. Một promise có thể ở trạng thái pending (chờ), fulfilled (hoàn thành) hoặc rejected (bị từ chối). Chuỗi .then().catch().finally() xử lý kết quả bất đồng bộ. async/await (ES8) là đường cú pháp: hàm async trả về Promise, await tạm dừng thực thi cho đến khi promise được giải quyết mà không chặn luồng.
// Tải dữ liệu bất đồng bộ trong 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('Tìm nạp thất bại:', error);
setLoading(false);
}
}
}
fetchUser();
return () => { cancelled = true; };
}, [userId]);
if (loading) return <ActivityIndicator />;
return (
<View>
<Text>{user?.name ?? 'Unknown'}</Text>
</View>
);
}Hook useEffect với hàm async fetchUser thực hiện yêu cầu HTTP khi thành phần được gắn kết. Cờ cancelled ngăn setState sau khi tháo gỡ — một vấn đề phổ biến trong React Native. Optional Chaining user?.name và Nullish Coalescing ?? xử lý undefined mà không có lỗi. ActivityIndicator hiển thị trong khi tải — một mẫu bất đồng bộ quen thuộc với mọi nhà phát triển JS.
React Native là một framework từ Meta (Facebook) để tạo ứng dụng di động gốc bằng JavaScript. Không giống như phương pháp WebView, React Native kết xuất các thành phần gốc thực sự (UIView cho iOS, ViewGroup cho Android). Mã JS chạy trong một luồng riêng biệt (Hermes hoặc JSC) và giao tiếp với luồng UI gốc qua Bridge (kiến trúc cũ) hoặc JSI (kiến trúc Fabric mới).
React Native bao gồm luồng JS (mã của bạn), luồng gốc (UI) và Bridge/JSI để tương tác giữa chúng. Trong kiến trúc cũ (Bridge), các thông báo JSON được tuần tự hóa và truyền không đồng bộ — điều này tạo ra độ trễ trong các hoạt ảnh nhanh. Kiến trúc Fabric mới (React Native 0.68+) sử dụng JSI (JavaScript Interface) — tương tác JS trực tiếp với các đối tượng C++ mà không cần tuần tự hóa.
// Thành phần React Native với API gốc
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>
);
}Thành phần LocationTracker minh họa làm việc với API định vị gốc. Platform.OS phân biệt Android và iOS. PermissionsAndroid.request là hộp thoại quyền gốc của Android. Geolocation.getCurrentPosition — một mô-đun từ @react-native-community/geolocation, được cài đặt qua npm. React Native cung cấp giao diện JS cho camera, Bluetooth, gia tốc kế và các cảm biến khác.
Ionic là một framework cho ứng dụng di động lai sử dụng WebView để kết xuất HTML/CSS/JS. Không giống React Native, Ionic không tạo thành phần gốc — ứng dụng chạy bên trong một vùng chứa web (WebView) trên iOS (WKWebView) và Android (Android WebView). Điều này cho phép tái sử dụng 100% mã web nhưng hạn chế hiệu suất của các hoạt ảnh phức tạp.
Apache Cordova là nền tảng của Ionic, cung cấp quyền truy cập vào các API gốc thông qua plugin JavaScript. Camera, GPS, danh bạ, hệ thống tệp — tất cả đều có sẵn qua cordova-plugin-*. Ionic 7+ sử dụng Capacitor — người kế nhiệm Cordova với hiệu suất tốt hơn, hỗ trợ ESM và truy cập trực tiếp vào iOS/Android SDK qua Swift và Kotlin.
| Đặc điểm | React Native | Ionic (Capacitor) | Cordova |
|---|---|---|---|
| Kết xuất UI | Thành phần gốc | WebView (WKWebView) | WebView |
| Ngôn ngữ | JS/TS | JS/TS + HTML/CSS | JS/TS + HTML/CSS |
| API gốc | Bridge/JSI + mô-đun | Capacitor Plugins | Cordova Plugins |
| Hiệu suất | Cao (60 FPS) | Trung bình (phụ thuộc WebView) | Trung bình |
| Kích thước APK | ~25-40 MB | ~10-15 MB | ~8-12 MB |
| Tái sử dụng mã | ~60% mã | ~95% mã với phiên bản web | ~95% |
Công cụ phát triển JS cho ứng dụng di động bao gồm Node.js, npm/yarn, Expo, React Native CLI và Metro bundler. Node.js là môi trường chạy JS bên ngoài trình duyệt, nền tảng của hệ sinh thái. npm (Node Package Manager) là trình quản lý gói với hơn 2 triệu thư viện. npx là tiện ích chạy gói npm mà không cần cài đặt.
Expo là một lớp trên React Native giúp đơn giản hóa phát triển: không yêu cầu Xcode/Android Studio để bắt đầu, cung cấp Managed Workflow với các thư viện được cài đặt sẵn. Expo Application Services (EAS) — xây dựng và xuất bản trên đám mây. Metro là trình đóng gói React Native, tập hợp mã JS và các phụ thuộc vào một tệp duy nhất. Hermes là công cụ JS từ Meta được tối ưu hóa cho thiết bị di động với biên dịch AOT.
// package.json — cấu hình dự án 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"
}
}Tệp package.json là nền tảng của bất kỳ dự án JS nào. Các script start, android, ios khởi chạy Metro bundler và bản dựng. Các phụ thuộc được chia thành dependencies (thời gian chạy) và devDependencies (kiểm thử, linter). React Navigation là bộ định tuyến tiêu chuẩn. Jest là framework kiểm thử. ESLint là trình phân tích tĩnh kiểm tra phong cách mã và các lỗi tiềm ẩn.
Câu hỏi thường gặp
JavaScript (JS) là một ngôn ngữ lập trình với kiểu động, kế thừa nguyên mẫu và mô hình vòng lặp sự kiện đơn luồng. Được tạo ra năm 1995. Trong phát triển di động, nó được sử dụng qua React Native (thành phần gốc + logic JS) và Ionic (vùng chứa WebView). Là ngôn ngữ được sử dụng nhiều nhất trong năm thứ mười liên tiếp theo dữ liệu Stack Overflow.
React Native thực thi JS trong một luồng riêng (Hermes hoặc JSC). Luồng JS quản lý logic và trạng thái, luồng gốc kết xuất các thành phần UI. Trao đổi dữ liệu qua Bridge (kiến trúc cũ, tuần tự hóa JSON) hoặc JSI (kiến trúc Fabric mới, truy cập C++ trực tiếp). Hermes là công cụ JS từ Meta với biên dịch AOT giảm thời gian khởi động 50%.
JavaScript được gõ động — kiểu được kiểm tra trong thời gian chạy. TypeScript thêm gõ tĩnh với kiểm tra biên dịch, giao diện, generics và liệt kê. Bất kỳ mã JS nào cũng là TypeScript hợp lệ. TS được biên dịch (dịch chuyển) thành JS thuần qua tsc hoặc Babel. Trong React Native, TS được sử dụng trong ~65% dự án mới.
Chính: React Native (Meta) — nền tảng kết xuất gốc với Bridge/Fabric. Ionic (Capacitor) — vùng chứa WebView với quyền truy cập API gốc qua plugin. Apache Cordova — tiền thân của Ionic, cũng là WebView. NativeScript — truy cập trực tiếp API gốc không qua WebView. Expo — lớp trên React Native để tạo mẫu nhanh không cần thiết lập bản dựng gốc.
Tính bất đồng bộ JS dựa trên vòng lặp sự kiện: call stack (mã đồng bộ) → microtask queue (Promise.then) → macrotask queue (setTimeout, I/O). Promise là đối tượng cho các thao tác bất đồng bộ. async/await là đường cú pháp trên Promise. Mô hình đơn luồng không chặn UI, nhưng các tác vụ tốn CPU yêu cầu Web Workers hoặc luồng riêng (trong React Native — InteractionManager).
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm