Buổi 5: Mảng, Object & Destructuring
Loại buổi: Lý thuyết
Thời lượng: 120 phút
Dự án: To-Do App (đã có chức năng thêm công việc từ buổi 4)
🎯 Mục tiêu học tập
Sau buổi học này, bạn sẽ có thể:
- ✅ Khai báo và sử dụng mảng (Array)
- ✅ Sử dụng các phương thức mảng phổ biến (push, pop, filter, map...)
- ✅ Khai báo và sử dụng object
- ✅ Truy cập và thao tác với object
- ✅ Sử dụng destructuring để rút gọn code
- ✅ Áp dụng vào quản lý danh sách công việc
🧠 Nội dung chính
1. Mảng (Array)
Mảng là tập hợp các giá trị được sắp xếp theo thứ tự.
1.1. Khai báo mảng
// Cách 1: Array literal (khuyến nghị)
let danhSach = ['Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C'];
// Cách 2: Array constructor
let danhSach2 = new Array('A', 'B', 'C');
// Mảng rỗng
let mangRong = [];
// Mảng hỗn hợp (có thể chứa nhiều kiểu dữ liệu)
let mangHonHop = [1, 'hello', true, null, { name: 'A' }];1.2. Truy cập phần tử
let danhSach = ['Nguyễn Văn A', 'Trần Thị B', 'Lê Văn C'];
console.log(danhSach[0]); // "Nguyễn Văn A" (phần tử đầu tiên)
console.log(danhSach[1]); // "Trần Thị B"
console.log(danhSach[2]); // "Lê Văn C"
console.log(danhSach.length); // 3 (số phần tử)
// Truy cập phần tử cuối
console.log(danhSach[danhSach.length - 1]); // "Lê Văn C"1.3. Thêm/Xóa phần tử
Thêm vào cuối:
let danhSach = ['A', 'B'];
danhSach.push('C'); // Thêm vào cuối
console.log(danhSach); // ['A', 'B', 'C']Xóa phần tử cuối:
let phanTuCuoi = danhSach.pop(); // Xóa và trả về phần tử cuối
console.log(phanTuCuoi); // 'C'
console.log(danhSach); // ['A', 'B']Thêm vào đầu:
danhSach.unshift('X'); // Thêm vào đầu
console.log(danhSach); // ['X', 'A', 'B']Xóa phần tử đầu:
let phanTuDau = danhSach.shift(); // Xóa và trả về phần tử đầu
console.log(phanTuDau); // 'X'
console.log(danhSach); // ['A', 'B']Splice (thêm/xóa ở vị trí bất kỳ):
let danhSach = ['A', 'B', 'C', 'D'];
// splice(vị trí, số phần tử xóa, ...phần tử thêm)
danhSach.splice(2, 1, 'X'); // Xóa 1 phần tử ở vị trí 2, thêm 'X'
console.log(danhSach); // ['A', 'B', 'X', 'D']1.4. Các phương thức mảng phổ biến
forEach - Duyệt mảng:
let danhSach = ['A', 'B', 'C'];
danhSach.forEach(function(item, index) {
console.log(`${index}: ${item}`);
});
// Output: 0: A, 1: B, 2: Cmap - Tạo mảng mới từ mảng cũ:
let so = [1, 2, 3, 4, 5];
let soBinhPhuong = so.map(function(item) {
return item * item;
});
console.log(soBinhPhuong); // [1, 4, 9, 16, 25]
// Arrow function
let soBinhPhuong2 = so.map(x => x * x);filter - Lọc phần tử:
let so = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let soChan = so.filter(function(item) {
return item % 2 === 0;
});
console.log(soChan); // [2, 4, 6, 8, 10]find - Tìm phần tử đầu tiên:
let danhSach = [
{ id: 1, ten: 'Công việc A' },
{ id: 2, ten: 'Công việc B' },
{ id: 3, ten: 'Công việc C' }
];
let congViec = danhSach.find(function(item) {
return item.id === 2;
});
console.log(congViec); // { id: 2, ten: 'Công việc B' }includes - Kiểm tra có chứa:
let danhSach = ['A', 'B', 'C'];
console.log(danhSach.includes('B')); // true
console.log(danhSach.includes('D')); // falseindexOf - Tìm vị trí:
let danhSach = ['A', 'B', 'C'];
console.log(danhSach.indexOf('B')); // 1
console.log(danhSach.indexOf('D')); // -1 (không tìm thấy)slice - Cắt mảng:
let danhSach = ['A', 'B', 'C', 'D', 'E'];
let cat = danhSach.slice(1, 3); // Từ vị trí 1 đến 3 (không bao gồm 3)
console.log(cat); // ['B', 'C']join - Nối thành chuỗi:
let danhSach = ['A', 'B', 'C'];
let chuoi = danhSach.join(' - ');
console.log(chuoi); // "A - B - C"2. Object (Đối tượng)
Object là tập hợp các cặp key-value.
2.1. Khai báo object
// Cách 1: Object literal (khuyến nghị)
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20,
maSo: 'SV001',
diemTrungBinh: 8.5
};
// Cách 2: Object constructor
let sinhVien2 = new Object();
sinhVien2.hoTen = 'Trần Thị B';2.2. Truy cập thuộc tính
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20,
maSo: 'SV001'
};
// Cách 1: Dot notation
console.log(sinhVien.hoTen); // "Nguyễn Văn A"
console.log(sinhVien.tuoi); // 20
// Cách 2: Bracket notation
console.log(sinhVien['hoTen']); // "Nguyễn Văn A"
console.log(sinhVien['tuoi']); // 20
// Bracket notation hữu ích khi key là biến
let key = 'hoTen';
console.log(sinhVien[key]); // "Nguyễn Văn A"2.3. Thêm/Sửa/Xóa thuộc tính
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20
};
// Thêm thuộc tính
sinhVien.diaChi = '123 Đường ABC';
sinhVien['maSo'] = 'SV001';
// Sửa thuộc tính
sinhVien.tuoi = 21;
// Xóa thuộc tính
delete sinhVien.diaChi;
console.log(sinhVien); // { hoTen: 'Nguyễn Văn A', tuoi: 21, maSo: 'SV001' }2.4. Object trong Object (Nested)
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20,
diaChi: {
soNha: '123',
duong: 'Đường ABC',
phuong: 'Phường 1',
quan: 'Quận 1'
}
};
console.log(sinhVien.diaChi.quan); // "Quận 1"2.5. Object với hàm (Method)
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20,
layThongTin: function() {
return `${this.hoTen}, ${this.tuoi} tuổi`;
},
// Arrow function (ES6)
inThongTin: () => {
console.log(`${sinhVien.hoTen}, ${sinhVien.tuoi} tuổi`);
}
};
console.log(sinhVien.layThongTin()); // "Nguyễn Văn A, 20 tuổi"
sinhVien.inThongTin(); // "Nguyễn Văn A, 20 tuổi"2.6. Duyệt object
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20,
maSo: 'SV001'
};
// for...in
for (let key in sinhVien) {
console.log(`${key}: ${sinhVien[key]}`);
}
// Object.keys()
let keys = Object.keys(sinhVien);
console.log(keys); // ['hoTen', 'tuoi', 'maSo']
// Object.values()
let values = Object.values(sinhVien);
console.log(values); // ['Nguyễn Văn A', 20, 'SV001']
// Object.entries()
let entries = Object.entries(sinhVien);
console.log(entries); // [['hoTen', 'Nguyễn Văn A'], ['tuoi', 20], ...]3. Destructuring (Phân rã)
Destructuring cho phép giải nén giá trị từ mảng hoặc object.
3.1. Array Destructuring
let danhSach = ['Nguyễn Văn A', 20, 'SV001'];
// Cách cũ
let hoTen = danhSach[0];
let tuoi = danhSach[1];
let maSo = danhSach[2];
// Destructuring
let [hoTen, tuoi, maSo] = danhSach;
console.log(hoTen); // "Nguyễn Văn A"
console.log(tuoi); // 20
// Bỏ qua phần tử
let [hoTen, , maSo] = danhSach; // Bỏ qua phần tử thứ 2
// Giá trị mặc định
let [a, b = 0] = [1];
console.log(a); // 1
console.log(b); // 0 (mặc định)3.2. Object Destructuring
let sinhVien = {
hoTen: 'Nguyễn Văn A',
tuoi: 20,
maSo: 'SV001'
};
// Destructuring
let { hoTen, tuoi, maSo } = sinhVien;
console.log(hoTen); // "Nguyễn Văn A"
// Đổi tên biến
let { hoTen: ten, tuoi: soTuoi } = sinhVien;
console.log(ten); // "Nguyễn Văn A"
console.log(soTuoi); // 20
// Giá trị mặc định
let { hoTen, tuoi, diaChi = 'Chưa có' } = sinhVien;
console.log(diaChi); // "Chưa có"3.3. Destructuring trong hàm
// Object destructuring trong tham số
function inThongTin({ hoTen, tuoi }) {
console.log(`${hoTen}, ${tuoi} tuổi`);
}
let sinhVien = { hoTen: 'Nguyễn Văn A', tuoi: 20 };
inThongTin(sinhVien); // "Nguyễn Văn A, 20 tuổi"💻 Ví dụ minh họa
Ví dụ 1: Quản lý danh sách công việc
// Mảng công việc
let danhSachCongViec = [
{ id: 1, ten: 'Học JavaScript', trangThai: 'chua lam' },
{ id: 2, ten: 'Làm bài tập', trangThai: 'dang lam' },
{ id: 3, ten: 'Nộp bài', trangThai: 'chua lam' }
];
// Thêm công việc mới
function themCongViec(ten, trangThai = 'chua lam') {
let idMoi = danhSachCongViec.length + 1;
danhSachCongViec.push({ id: idMoi, ten, trangThai });
}
// Tìm công việc theo ID
function timCongViec(id) {
return danhSachCongViec.find(cv => cv.id === id);
}
// Xóa công việc
function xoaCongViec(id) {
danhSachCongViec = danhSachCongViec.filter(cv => cv.id !== id);
}
// Lọc công việc theo trạng thái
function locCongViec(trangThai) {
return danhSachCongViec.filter(cv => cv.trangThai === trangThai);
}
// Sử dụng
themCongViec('Đọc sách');
console.log(timCongViec(2));
xoaCongViec(1);
console.log(locCongViec('chua lam'));Ví dụ 2: Tính điểm trung bình
let danhSachDiem = [
{ mon: 'Toán', diem: 8.5 },
{ mon: 'Lý', diem: 9.0 },
{ mon: 'Hóa', diem: 7.5 }
];
// Tính tổng điểm
let tongDiem = danhSachDiem.reduce(function(tong, item) {
return tong + item.diem;
}, 0);
// Tính điểm trung bình
let diemTrungBinh = tongDiem / danhSachDiem.length;
console.log(`Điểm trung bình: ${diemTrungBinh.toFixed(2)}`); // 8.33Ví dụ 3: Destructuring với công việc
let congViec = {
id: 1,
ten: 'Học JavaScript',
moTa: 'Học về mảng và object',
trangThai: 'chua lam',
doUuTien: 'cao'
};
// Destructuring
let { id, ten, trangThai } = congViec;
console.log(`${id}: ${ten} - ${trangThai}`);
// Trong hàm
function capNhatTrangThai({ id, trangThai }) {
console.log(`Cập nhật công việc ${id} thành ${trangThai}`);
}
capNhatTrangThai({ id: 1, trangThai: 'hoan thanh' });🧪 Quiz cuối buổi (7 câu)
Câu 1: Kết quả của [1, 2, 3].push(4) là gì?
A. [1, 2, 3, 4]
B. 4 (độ dài mảng)
C. true
D. undefined
Đáp án: B (push trả về độ dài mảng mới)
Câu 2: Cách nào đúng để truy cập thuộc tính ten của object sv?
A. sv.ten
B. sv['ten']
C. Cả A và B
D. sv[ten] (thiếu dấu nháy)
Đáp án: C
Câu 3: Kết quả của [1, 2, 3].map(x => x * 2) là gì?
A. [2, 4, 6]
B. [1, 2, 3]
C. [1, 4, 9]
D. Lỗi
Đáp án: A
Câu 4: Destructuring đúng cho let [a, b] = [1, 2, 3]?
A. a = 1, b = 2
B. a = [1, 2], b = 3
C. Lỗi
D. a = 1, b = [2, 3]
Đáp án: A
Câu 5: Phương thức nào dùng để lọc mảng?
A. map
B. filter
C. find
D. forEach
Đáp án: B
Câu 6: Kết quả của let {x, y} = {x: 1, y: 2, z: 3}?
A. x = 1, y = 2
B. x = {x: 1}, y = {y: 2}
C. Lỗi
D. x = undefined, y = undefined
Đáp án: A
Câu 7: Cách nào xóa phần tử cuối cùng của mảng?
A. array.remove()
B. array.pop()
C. array.delete()
D. array.shift()
Đáp án: B
📝 Bài tập về nhà (chuẩn bị cho buổi 6)
- Tạo mảng
danhSachCongViecchứa các object công việc - Viết hàm
themCongViec(ten, moTa)thêm công việc mới - Viết hàm
hienThiDanhSach()hiển thị tất cả công việc - Dùng
mapđể tạo mảng chỉ chứa tên công việc - Dùng
filterđể lọc công việc chưa hoàn thành
🔗 Tài liệu tham khảo
Chúc bạn học tập tốt! 🚀