So sánh cơ bản phương thức mảng
| Tính năng | map | forEach |
| Giá trị trả về | Mảng mới | undefined |
| Mục đích | Biến đổi dữ liệu | Thao tác phụ |
| Ngắt vòng lặp | Không hỗ trợ | Không hỗ trợ |
| Tham số hàm | (giá trị, chỉ số, mảng) | (giá trị, chỉ số, mảng) |
Cạm bẫy ẩn của phương thức map
Bẫy 1: Quên trả về giá trị
const mangSo = [7, 8, 9];
const nhanDoi = mangSo.map(so => {
so * 2; // Thiếu return
});
console.log(nhanDoi); // [undefined, undefined, undefined]
Bẫy 2: Thay đổi mảng gốc
const nguoiDung = [{ten: 'Minh'}, {ten: 'Hùng'}];
nguoiDung.map(user => {
user.tuoi = 25; // Thay đổi thuộc tính
return user;
});
console.log(nguoiDung[0].tuoi); // 25
Bẫy 3: Xử lý mảng thưa
const mangThua = [5, , 15];
const ketQua = mangThua.map(x => x * 3);
console.log(ketQua); // [15, empty, 45]
Cạm bẫy khi dùng forEach
Bẫy 1: Không thể dừng vòng lặp
const giaTri = [10, 20, 30, 40];
giaTri.forEach(val => {
if (val > 25) return;
console.log(val); // Vẫn xử lý 40
});
// Kết quả: 10, 20, 30
Bẫy 2: Xử lý bất đồng bộ
const duongDan = ['link1', 'link2'];
duongDan.forEach(async url => {
const duLieu = await layDuLieu(url);
console.log(duLieu); // Thứ tự không xác định
});
Trường hợp đặc biệt từ wtfjs
Cộng mảng
console.log([10, 20] + [30, 40]);
// "10,2030,40" (chuyển thành chuỗi)
Mảng làm khóa đối tượng
const obj = {};
const a = 5, b = 6;
obj[[a, b]] = true;
console.log(obj["5,6"]); // true
Thực hành tốt nhất
Luôn trả về giá trị với map
// Đúng:
const ketQua = mangSo.map(x => x * 3);
// Hoặc:
const ketQua = mangSo.map(x => {
return x * 3;
});
Phân biệt chức năng
// Biến đổi dữ liệu:
const ten = nguoiDung.map(user => user.ten);
// Thao tác phụ:
nguoiDung.forEach(user => {
user.lanDangNhapCuoi = new Date();
});
Xử lý bất đồng bộ
async function xuLy(duongDan) {
for (const url of duongDan) {
const duLieu = await layDuLieu(url);
console.log(duLieu); // Tuần tự
}
}
Kết luận
- Sử dụng
map cho biến đổi, forEach cho thao tác phụ
- Kiểm tra kiểu giá trị trả về
- Lưu ý đặc tính tham chiếu
- Tránh xử lý bất đồng bộ trong
forEach