Bảng Điều Khiển Ôn Tập Android

Kotlin • MVVM • Flow • REST API • Compose • Testing

Về Lộ trình 2 tháng
Tuần 2Giai đoạn 2 — JavaScript/TypeScript từ cơ bản

Tuần 2JavaScript & TypeScript cơ bản

Đọc và viết được các đoạn JavaScript/TypeScript cơ bản, giải bài toán logic đơn giản.

1Ngày 1 — Node.js & chương trình TypeScript đầu tiên

Ghi nhớ

Mục tiêu hôm nay: cài Node.js, chạy được file TypeScript đầu tiên, và hiểu biến let/const cùng kiểu dữ liệu cơ bản.

Node.js là một môi trường cho phép chạy JavaScript/TypeScript ngoài trình duyệt, ngay trên máy tính của bạn. Tuần này ta dùng Node.js để chạy các bài tập nhỏ trong terminal, trước khi chuyển sang xây app ở Tuần 3.

TypeScript là JavaScript được thêm phần khai báo kiểu dữ liệu (type). Nhờ đó, nhiều lỗi được máy phát hiện ngay lúc gõ code, thay vì phải chạy thử mới biết sai. File TypeScript có đuôi .ts và cần một công cụ như tsx hoặc ts-node để Node.js chạy được.

Biến (variable) là một cái tên dùng để lưu và gọi lại một giá trị. Trong TypeScript có hai cách khai báo: let cho biến có thể đổi giá trị sau này, const cho hằng số không đổi sau khi gán. Nên ưu tiên dùng const, chỉ dùng let khi biết chắc giá trị sẽ thay đổi.

Khai báo biến và kiểu dữ liệu cơ bản

const ten: string = "Minh";
let tuoi: number = 25;
const daKetHon: boolean = false;

console.log(ten, tuoi, daKetHon);

Mẹo

Ví dụ so sánh: biến giống một cái hộp có dán nhãn tên. const là hộp dán keo kín sau khi bỏ đồ vào — không đổi được đồ bên trong; let là hộp có thể mở ra thay đồ khác bất cứ lúc nào.

  • Bài tập 1: Cài Node.js, tạo file hello.ts in ra dòng chữ 'Xin chào' bằng console.log.
  • Bài tập 2: Khai báo 3 biến const lưu tên, tuổi, thành phố của bạn rồi in ra bằng console.log.
  • Bài tập 3: Thử khai báo một biến const rồi gán lại giá trị cho nó, quan sát lỗi TypeScript báo.

Lưu ý

Lỗi thường gặp: dùng = (dấu gán) khi định so sánh hai giá trị — trong TypeScript so sánh phải dùng === (sẽ học ở Ngày 2). Ngoài ra khai báo const rồi gán lại giá trị sẽ báo lỗi ngay khi biên dịch.

  • Tự kiểm tra: let và const khác nhau ở điểm nào?
  • Tự kiểm tra: Vì sao TypeScript giúp phát hiện lỗi sớm hơn JavaScript thường?
  • Tự kiểm tra: Kể tên 3 kiểu dữ liệu cơ bản đã học.

2Ngày 2 — Kiểu dữ liệu, toán tử & template string

Ghi nhớ

Mục tiêu: dùng đúng các toán tử số học, so sánh, logic và nối chuỗi bằng template string.

Toán tử số học gồm + (cộng), - (trừ), * (nhân), / (chia), % (lấy phần dư). Toán tử so sánh gồm === (bằng, đúng cả giá trị lẫn kiểu), !== (khác), >, <, >=, <=. Toán tử logic gồm && (và), || (hoặc), ! (phủ định).

Mẹo

Luôn dùng === thay vì == để so sánh. == có thể tự ép kiểu trước khi so sánh (ví dụ '5' == 5 cho kết quả true) và dễ gây lỗi khó nhận ra; === so sánh chính xác cả kiểu dữ liệu.

Template string là cách viết chuỗi bằng dấu backtick (`) cho phép chèn thẳng biến vào giữa chữ bằng ${...}, thay vì phải nối chuỗi bằng dấu +.

Toán tử và template string

const a = 7;
const b = 2;
console.log(a % b); // 1
console.log(a > b && b > 0); // true

const ten = "Minh";
const tuoi = 25;
console.log(`Tôi tên ${ten}, năm nay ${tuoi} tuổi.`);
  • Bài tập 1: Tính và in ra kết quả của 17 % 5, sau đó giải thích vì sao ra kết quả đó.
  • Bài tập 2: Dùng template string viết một câu tự giới thiệu có chèn tên và tuổi.
  • Bài tập 3: Viết biểu thức logic kiểm tra một số vừa lớn hơn 0 vừa nhỏ hơn 100.

Lưu ý

Lỗi thường gặp: dùng dấu nháy đơn/kép thường (' hoặc ") thay vì backtick (`) khi viết template string — khi đó ${...} sẽ không hoạt động và bị in ra y nguyên như chữ thường.

  • Tự kiểm tra: === khác == ở điểm nào? Vì sao nên dùng ===?
  • Tự kiểm tra: Toán tử % dùng để làm gì?
  • Tự kiểm tra: Cú pháp template string trông như thế nào?

3Ngày 3 — Câu điều kiện (if/else, switch)

Ghi nhớ

Mục tiêu: rẽ nhánh logic đúng bằng if/else và switch.

if/else cho phép chương trình chọn một trong nhiều nhánh xử lý tuỳ theo điều kiện đúng hay sai. Có thể nối nhiều điều kiện bằng else if khi cần kiểm tra lần lượt nhiều trường hợp.

if / else if / else xếp loại điểm

const diem = 7.5;

if (diem >= 8) {
  console.log("Giỏi");
} else if (diem >= 6.5) {
  console.log("Khá");
} else {
  console.log("Trung bình");
}

switch dùng khi cần so sánh cùng một giá trị với nhiều lựa chọn cụ thể — đọc gọn hơn if/else if nối dài. Mỗi case cần có break để dừng lại, nếu không chương trình sẽ 'rơi' tiếp xuống case bên dưới.

switch theo ngày trong tuần

const thu = 2;

switch (thu) {
  case 1:
    console.log("Chủ nhật");
    break;
  case 2:
    console.log("Thứ Hai");
    break;
  default:
    console.log("Ngày khác");
}
  • Bài tập 1: Viết chương trình xếp loại học lực từ điểm trung bình (Giỏi/Khá/Trung bình/Yếu).
  • Bài tập 2: Dùng switch in ra tên tháng có bao nhiêu ngày (thử với tháng 2, tháng 4, tháng 1).

Lưu ý

Lỗi thường gặp: quên break trong switch khiến code chạy tiếp xuống case bên dưới dù đã khớp case đúng (gọi là fallthrough).

  • Tự kiểm tra: Khi nào nên dùng switch thay vì nhiều else if?
  • Tự kiểm tra: Điều gì xảy ra nếu quên break trong switch?

4Ngày 4 — Vòng lặp (for / while / for-of)

Ghi nhớ

Mục tiêu: lặp qua số và lặp qua mảng đúng cách bằng for, while, for-of.

Vòng lặp for dùng khi biết trước số lần lặp: có phần khởi tạo, điều kiện dừng, và bước tăng/giảm. Vòng lặp while dùng khi chưa biết chính xác số lần lặp, chỉ biết điều kiện khi nào thì dừng.

for và while

for (let i = 1; i <= 5; i++) {
  console.log(i);
}

let dem = 0;
while (dem < 3) {
  console.log("lặp", dem);
  dem++;
}

for-of dùng riêng để lặp qua từng phần tử của một mảng (array), gọn hơn for thường vì không cần tự quản lý chỉ số.

for-of lặp qua mảng

const monHoc = ["Toán", "Văn", "Anh"];
for (const mon of monHoc) {
  console.log(mon);
}
  • Bài tập 1: In bảng cửu chương của số 5 (5x1 đến 5x10) bằng vòng lặp for.
  • Bài tập 2: Dùng while đếm và in ra các số chẵn từ 0 đến 20.
  • Bài tập 3: Dùng for-of in ra từng phần tử của một mảng tên bạn bè.

Lưu ý

Lỗi thường gặp: quên tăng biến đếm trong while (hoặc viết sai điều kiện dừng) khiến vòng lặp chạy mãi không dừng (vòng lặp vô hạn).

  • Tự kiểm tra: Khi nào nên dùng for, khi nào nên dùng while?
  • Tự kiểm tra: for-of khác gì so với for thường khi lặp qua mảng?

5Ngày 5 — Function

Ghi nhớ

Mục tiêu: viết được function nhận đầu vào, xử lý và trả về kết quả, dùng cả function thường lẫn arrow function.

Function (hàm) là một khối code được đặt tên, nhận vào một số tham số (input), xử lý, và trả về kết quả (output) bằng từ khoá return. Function giúp tái sử dụng logic thay vì chép lại code nhiều lần.

Function thường và arrow function

function tinhTong(a: number, b: number): number {
  return a + b;
}

const tinhTich = (a: number, b: number): number => a * b;

console.log(tinhTong(2, 3)); // 5
console.log(tinhTich(2, 3)); // 6

Arrow function là cách viết ngắn gọn hơn của function thường, hay dùng khi truyền một hàm nhỏ làm tham số cho hàm khác (sẽ gặp nhiều ở Ngày 6 với map/filter). Tham số có thể có giá trị mặc định hoặc đánh dấu optional bằng dấu ? khi không bắt buộc phải truyền.

Tham số mặc định và optional

function chao(ten: string, loiChao: string = "Xin chào"): string {
  return `${loiChao}, ${ten}!`;
}

console.log(chao("Minh")); // Xin chào, Minh!
console.log(chao("Minh", "Chào buổi sáng"));
  • Bài tập 1: Viết function tính trung bình cộng của 3 số.
  • Bài tập 2: Viết function kiểm tra một số có phải số nguyên tố hay không, trả về boolean.
  • Bài tập 3: Viết arrow function nhận tên và trả về lời chào có dùng template string.

Lưu ý

Lỗi thường gặp: quên viết return khiến function luôn trả về undefined dù bên trong đã tính ra kết quả đúng.

  • Tự kiểm tra: Function nhận input và trả output ở đâu trong cú pháp?
  • Tự kiểm tra: Arrow function khác function thường ở điểm nào?

6Ngày 6 — Array & Object

Ghi nhớ

Mục tiêu: dùng được Array với map/filter/find/reduce, Object cơ bản và destructuring.

Array (mảng) lưu một danh sách giá trị theo thứ tự. Object lưu dữ liệu theo cặp tên-giá trị (key-value), dùng khi mỗi thông tin có một cái tên rõ ràng, ví dụ một người có ten, tuoi, thanhPho.

Object cơ bản

const nguoiDung = {
  ten: "Minh",
  tuoi: 25,
};

console.log(nguoiDung.ten);
const { ten, tuoi } = nguoiDung; // destructuring
console.log(ten, tuoi);

map, filter, find, reduce là các method rất hay dùng trên Array. map biến mỗi phần tử thành một giá trị mới và trả về mảng mới. filter giữ lại những phần tử thoả điều kiện. find trả về phần tử đầu tiên thoả điều kiện. reduce gộp cả mảng lại thành một giá trị duy nhất.

map / filter / find / reduce

const so = [1, 2, 3, 4, 5];

const gapDoi = so.map((n) => n * 2); // [2,4,6,8,10]
const soChan = so.filter((n) => n % 2 === 0); // [2,4]
const dauTienLonHon3 = so.find((n) => n > 3); // 4
const tong = so.reduce((acc, n) => acc + n, 0); // 15

Mẹo

map/filter/find/reduce đều trả về giá trị mới, không sửa mảng gốc. Đây là cách viết quen thuộc trong React Native mà bạn sẽ dùng liên tục để biến dữ liệu từ API thành danh sách hiển thị trên màn hình.

  • Bài tập 1: Cho mảng điểm số, dùng filter lấy ra các điểm từ 5 trở lên.
  • Bài tập 2: Cho mảng object { ten, tuoi }, dùng map lấy ra mảng chỉ chứa tên.
  • Bài tập 3: Dùng reduce tính tổng tuổi của tất cả người trong mảng object trên.

Lưu ý

Lỗi thường gặp: nhầm map (luôn trả về mảng mới cùng độ dài) với forEach (chỉ để chạy code, không trả về gì) — dùng forEach rồi mong có mảng kết quả sẽ ra undefined.

  • Tự kiểm tra: map và filter khác nhau ở điểm nào?
  • Tự kiểm tra: reduce dùng để làm gì?
  • Tự kiểm tra: destructuring object để làm gì?

7Ngày 7 — TypeScript cơ bản & ôn tập tuần

Ghi nhớ

Mục tiêu: dùng được type/interface cơ bản, phân biệt undefined và null; ôn lại cả tuần.

type và interface đều dùng để mô tả 'hình dạng' của một object: nó có những thuộc tính gì, kiểu dữ liệu ra sao. Khai báo trước một type/interface giúp TypeScript báo lỗi ngay nếu bạn dùng thiếu hoặc sai kiểu thuộc tính.

interface mô tả một object

interface NguoiDung {
  ten: string;
  tuoi: number;
  email?: string; // optional
}

const user: NguoiDung = { ten: "Minh", tuoi: 25 };

undefined nghĩa là một biến chưa được gán giá trị gì cả. null nghĩa là biến được gán chủ đích 'không có giá trị'. Đánh dấu một thuộc tính là optional bằng dấu ? (như email? ở trên) nghĩa là thuộc tính đó có thể không tồn tại (undefined).

Mẹo

Lợi ích lớn nhất của TypeScript là bắt lỗi ngay lúc viết code (compile-time) thay vì phải chạy thử app mới phát hiện ra, ví dụ gõ nhầm tên thuộc tính hoặc truyền sai kiểu dữ liệu cho function.

  • Bài tập 1: Viết interface Sach gồm tieuDe (string), soTrang (number), daDoc (boolean).
  • Bài tập 2 (sản phẩm cuối tuần): Viết một chương trình console (Node.js) bằng TypeScript: khai báo một mảng object NguoiDung (theo interface ở trên), dùng filter/map để lọc và in ra danh sách người từ 18 tuổi trở lên.

Lưu ý

Lỗi thường gặp: khai báo thuộc tính kiểu any (bỏ qua kiểm tra kiểu) chỉ để hết báo lỗi nhanh — làm vậy mất hết lợi ích của TypeScript, nên luôn cố khai báo đúng kiểu thật.

  • Ôn tập tuần: Kể lại cách khai báo biến let/const và các kiểu dữ liệu cơ bản.
  • Ôn tập tuần: Viết một if/else và một switch cho cùng một bài toán.
  • Ôn tập tuần: Viết một function dùng map để biến đổi một mảng.
  • Ôn tập tuần: interface dùng để làm gì? undefined khác null ở điểm nào?

Checklist theo dõi

Tick những gì học viên đã đạt

0/4