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
thiskhi 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ảnglocaleCompare()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