Giải Bài Tập JavaScript: 10 Câu Hỏi Trung Bình (Phần 1)

Các Khái Niệm Trọng Tâm

Array.from(): Chuyển đổi đối tượng giống mảng (Array-like) hoặc đối tượng lặp được (Iterable) thành mảng thực sự.

  • Tham số thứ 2: Hàm callback tương tự Array.prototype.map để xử lý từng phần tử
  • Tham số thứ 3: Định nghĩa ngữ cảnh this khi thực thi callback
  • Công dụng chính:
    • Chuyển NodeList, arguments thành mảng
    • Tạo mảng số liên tiếp: Array.from({ length: 5 }, (_, i) => i + 1)

Sắp xếp mảng:

arr.sort((a, b) => a - b); // Tăng dần
arr.sort((a, b) => b - a); // Giảm dần
// Sắp xếp chuỗi không phân biệt hoa thường
arr.sort((a, b) => a.localeCompare(b));

filter() và delete:

// Xóa phần tử tại index mà không thay đổi mảng gốc
const newArray = originalArray.filter((_, index) => index !== targetIndex);

DOM Manipulation:

  • element.innerHTML: Thay đổi nội dung bên trong phần tử
  • element.outerHTML: Thay thế toàn bộ phần tử (kể cả thẻ bao)
  • document.querySelector('#id'): Tìm phần tử theo CSS selector

Biểu Thức Chính Quy (Regex)

  • (...): Nhóm bắt (capturing group) - lưu kết quả khớp
  • (?:...): Nhóm không bắt (non-capturing group) - chỉ nhóm hóa
  • (?<=...): Positive lookbehind - kiểm tra phía trước
  • (?!...): Negative lookahead - kiểm tra phía sau
  • \B: Không phải biên từ (word boundary)
// Thêm dấu phẩy phân cách nghìn
function formatNumber(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

Sự Kiện DOM

  • DOM0 Level: Gán trực tiếp qua thuộc tính (onchange, onclick)
  • Chỉ đăng ký được 1 handler duy nhất
  • Ví dụ: inputElement.onchange = function() { /*...*/ };

Prototype và Kế Thừa

function Parent(name) {
  this.name = name;
}

function Child(name, age) {
  Parent.call(this, name);
  this.age = age;
}

// Kế thừa prototype
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.getAge = function() {
  return this.age;
};

Deep Copy vs Shallow Copy

Loại Cách triển khai Đặc điểm
Shallow Copy [...arr] hoặc arr.concat() Chỉ sao chép 1 tầng, object lồng nhau vẫn tham chiếu chung
Deep Copy JSON.parse(JSON.stringify(obj)) Không xử lý được function, undefined
Deep Copy structuredClone(obj) Hỗ trợ các kiểu phức tạp (Map, Set, Date)

Render Danh Sách Hiệu Quả

// Cách tốt nhất: map + join
ulElement.innerHTML = items.map(item => 
  <li>${item.name}</li>
).join('');
  • Tránh dùng += với innerHTML (gây reflow nhiều lần)
  • Sử dụng DocumentFragment khi cần thêm nhiều node

Xử Lý Ngày Tháng

const regDate = new Date('2023-01-15');
const today = new Date();
const diffDays = Math.floor((today - regDate) / (1000 * 60 * 60 * 24));

Bài Tập Mẫu: Sắp Xếp Danh Sách

Yêu cầu: Sắp xếp danh sách sản phẩm theo ID và render lại

function sortProducts() {
  const products = Array.from(document.querySelectorAll('#productList li'));
  const sorted = products.sort((a, b) => {
    return a.dataset.id.localeCompare(b.dataset.id);
  });
  
  productList.innerHTML = sorted.map(item => item.outerHTML).join('');
}

Giải thích:

  • Array.from() chuyển NodeList thành mảng
  • localeCompare() sắp xếp chuỗi an toàn
  • Dùng map().join('') để render hiệu quả

Bài Tập Mẫu: Phân Tách Ngàn

Yêu cầu: Thêm dấu phẩy phân cách nghìn cho số

function formatThousand(num) {
  return num.toString().replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}

Cơ chế:

  • (\d): Bắt 1 chữ số
  • (?=(\d{3})+$): Đảm bảo phía sau có nhóm 3 chữ số
  • $1,: Thêm dấu phẩy sau chữ số bắt được

Bài Tập Mẫu: Xác Thực Số CMND

Yêu cầu: Kiểm tra định dạng số chứng minh thư

function validateId(id) {
  return /^\d{9}(\d{3})?[0-9Xx]$/.test(id);
}

Giải thích regex:

  • ^: Bắt đầu chuỗi
  • \d{9}: 9 chữ số đầu
  • (\d{3})?: 3 chữ số tiếp theo (tùy chọn)
  • [0-9Xx]$: Ký tự cuối là số hoặc X/x

Thẻ: JavaScript Array Methods DOM Manipulation regular expressions Prototypal Inheritance

Đăng vào ngày 9 tháng 7 lúc 03:09