cv.cm

Lập trình · Ngôn ngữ lập trình

Hướng dẫn học JavaScript cơ bản cho người mới

6 phút đọc

Trả lời nhanh

JavaScript là ngôn ngữ lập trình của web: mọi trình duyệt đều chạy được nó, còn Node.js chạy nó trên máy chủ và dòng lệnh. Khai báo biến bằng const và let, viết hàm dạng khai báo hoặc arrow function, lưu dữ liệu trong mảng và đối tượng, và xử lý tác vụ chậm như yêu cầu mạng bằng promise và async/await. Chạy node hello.js hoặc mở console của trình duyệt để bắt đầu.

Mở Định dạng JSON

JavaScript là gì và dùng để làm gì

JavaScript là ngôn ngữ kiểu động, được chuẩn hóa với tên ECMAScript. Nó ra đời cho các trang web, nơi nó phản ứng với thao tác nhấp chuột, cập nhật trang và giao tiếp với máy chủ. Ngày nay nó còn chạy trên máy chủ và công cụ thông qua Node.js, Deno và Bun, trong ứng dụng máy tính (Electron) và ứng dụng di động (React Native). Lập trình viên front end, full-stack và bất kỳ ai xây dựng cho web đều dùng nó. Cú pháp hiện đại trong trang này (let, const, arrow function, class, module) đến từ ES2015 và các bản sau.

Chạy Hello, world

Cách 1: mở một trang web bất kỳ, nhấn F12 (hoặc Cmd+Option+J trên Mac) để mở console dành cho nhà phát triển rồi gõ dòng bên dưới. Cách 2: cài Node.js từ nodejs.org, lưu dòng đó thành hello.js rồi chạy.

console.log("Hello, world");
node hello.js
# Hello, world

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

Dùng const cho giá trị không gán lại và let cho giá trị thay đổi. Tránh var cũ, vì nó bỏ qua phạm vi khối. typeof cho biết kiểu của một giá trị.

KiểuVí dụtypeof
number42, 3.14, NaN"number"
bigint10n"bigint"
string"hi", 'hi', hi ${name} "string"
booleantrue, false"boolean"
undefinedundefined"undefined"
nullnull"object" (một điểm kỳ quặc từ lịch sử)
object{}, [], hàm"object" hoặc "function"
const name = "Ada";
let count = 1;
count += 1;
console.log(`${name} has ${count} items`); // Ada has 2 items
console.log(0.1 + 0.2);                    // 0.30000000000000004
console.log(Number("12") + 1, "12" + 1);   // 13 121

Điều khiển luồng: if, vòng lặp và so sánh bằng

Hãy luôn so sánh bằng === và !==. Toán tử lỏng == chuyển đổi kiểu trước nên 0 == "" là true.

const score = 72;
if (score >= 90) {
  console.log("A");
} else if (score >= 70) {
  console.log("B"); // B
} else {
  console.log("C");
}
for (let i = 0; i < 3; i++) console.log(i); // 0 1 2
for (const fruit of ["apple", "pear"]) console.log(fruit);
let n = 10;
while (n > 1) n = Math.floor(n / 2);
console.log(n); // 1

Hàm

Hàm cũng là giá trị: bạn có thể lưu chúng trong biến, truyền cho hàm khác và trả về. Arrow function là dạng ngắn hơn và rất phổ biến cho callback.

function greet(name, greeting = "Hello") {
  return `${greeting}, ${name}!`;
}
const square = (x) => x * x;
const sum = (...nums) => nums.reduce((a, b) => a + b, 0);
console.log(greet("Lin"));     // Hello, Lin!
console.log(square(5));        // 25
console.log(sum(1, 2, 3, 4));  // 10

Mảng và đối tượng

Mảng là danh sách có thứ tự; đối tượng ánh xạ khóa chuỗi sang giá trị. Cả hai đều được truyền theo tham chiếu. Map và Set là lựa chọn có sẵn khi khóa không phải chuỗi hoặc giá trị phải duy nhất.

const nums = [3, 1, 2];
nums.push(5);
const doubled = nums.map((n) => n * 2);
const evens = nums.filter((n) => n % 2 === 0);
console.log(doubled, evens);             // [ 6, 2, 4, 10 ] [ 2 ]
console.log([...nums].sort((a, b) => a - b)); // [ 1, 2, 3, 5 ]
const user = { name: "Ann", age: 31 };
user.city = "Oslo";
const { name, age } = user;              // destructuring
console.log(name, age, Object.keys(user)); // Ann 31 [ 'name', 'age', 'city' ]
console.log(JSON.stringify(user));       // {"name":"Ann","age":31,"city":"Oslo"}

Tính năng đặc trưng: mã bất đồng bộ với promise

JavaScript chạy mã của bạn trên một luồng với vòng lặp sự kiện (event loop). Các thao tác chậm (bộ hẹn giờ, mạng, tệp) không chặn; chúng trả về một promise sẽ hoàn tất sau. Hàm async cho phép bạn viết mã này từ trên xuống dưới với await.

const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function main() {
  console.log("start");
  await wait(500);
  console.log("half a second later");
  const [a, b] = await Promise.all([wait(100).then(() => 1), wait(200).then(() => 2)]);
  console.log(a + b); // 3
}
main();
console.log("main() was called"); // prints before "half a second later"

Class (class Dog extends Animal {}), module (import và export), optional chaining (user?.address?.city) và toán tử nullish (value ?? "default") là những tính năng hiện đại khác mà bạn sẽ dùng thường xuyên.

Xử lý lỗi

Hãy ném các đối tượng Error và bắt chúng bằng try/catch. Với hàm async, promise bị từ chối sẽ trở thành ngoại lệ tại await.

function parseAge(text) {
  const age = Number(text);
  if (!Number.isInteger(age) || age < 0) {
    throw new Error(`invalid age: ${text}`);
  }
  return age;
}
try {
  console.log(parseAge("41"));  // 41
  console.log(parseAge("abc"));
} catch (err) {
  console.log(err.message);     // invalid age: abc
} finally {
  console.log("done");
}

Một chương trình nhỏ hoàn chỉnh: tải dữ liệu và tóm tắt

Script Node.js này (Node 18 trở lên có sẵn fetch) tải JSON từ một API công khai và in ra bản tóm tắt ngắn. Lưu thành repos.mjs và chạy node repos.mjs nodejs.

const org = process.argv[2] ?? "nodejs";
async function topRepos(name, n = 3) {
  const res = await fetch(`https://api.github.com/orgs/${name}/repos?per_page=100`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const repos = await res.json();
  return repos
    .sort((a, b) => b.stargazers_count - a.stargazers_count)
    .slice(0, n)
    .map((r) => `${r.stargazers_count}\t${r.name}`);
}
try {
  const lines = await topRepos(org);
  console.log(lines.join("\n"));
} catch (err) {
  console.error("failed:", err.message);
  process.exitCode = 1;
}

Phần mở rộng .mjs biến tệp thành ES module, cho phép dùng await ở cấp cao nhất.

Những lỗi thường gặp của người mới

  • Dùng == thay cho ===, dẫn đến các chuyển đổi kiểu bất ngờ.
  • Quên await, nên bạn nhận được một đối tượng Promise đang chờ thay vì giá trị.
  • Tưởng const làm đối tượng bất biến. Nó chỉ ngăn gán lại; obj.x = 1 vẫn chạy được. Dùng Object.freeze nếu cần.
  • So sánh đối tượng hoặc mảng bằng ===, vốn kiểm tra danh tính chứ không phải nội dung.
  • Mất this khi truyền một phương thức làm callback. Hãy dùng arrow function hoặc .bind(obj).

Học tiếp ở đâu

Hãy đọc MDN JavaScript Guide, tài liệu tham khảo miễn phí đầy đủ nhất, và luyện tập với DOM của trình duyệt (document.querySelector, sự kiện). Sau đó học npm và module, một framework như React, Vue hoặc Svelte cho front end, hoặc Node.js cho máy chủ. Thêm TypeScript lên trên JavaScript sẽ cho bạn kiểu tĩnh và hỗ trợ trình soạn thảo tốt hơn.

Câu hỏi thường gặp

JavaScript có giống Java không?

Không. Đó là hai ngôn ngữ không liên quan dù tên giống nhau. Java là ngôn ngữ kiểu tĩnh, biên dịch thành bytecode JVM; JavaScript là kiểu động và chạy trong trình duyệt và Node.js.

Nên dùng let, const hay var?

Mặc định hãy dùng const và dùng let khi cần gán lại. Tránh var, vì nó có phạm vi hàm và bị hoisting, gây ra lỗi.

null và undefined khác nhau thế nào?

undefined nghĩa là biến hoặc thuộc tính chưa từng được gán giá trị. null là giá trị bạn cố ý gán để biểu thị không có gì.

Vì sao 0.1 + 0.2 không bằng 0.3?

Số trong JavaScript là số thực dấu phẩy động nhị phân 64 bit, không thể lưu chính xác 0.1. Hãy làm tròn khi hiển thị, hoặc dùng số nguyên (ví dụ xu) cho tiền.

Tôi có cần Node.js để học JavaScript không?

Không. Mọi trình duyệt đều chạy được JavaScript trong console dành cho nhà phát triển. Node.js hữu ích khi bạn muốn chạy script từ tệp hoặc xây dựng máy chủ và công cụ.

Tất cả hướng dẫn lập trình