1. Array & Object là gì?
Trong ứng dụng web, dữ liệu thường được tổ chức dưới hai dạng phổ biến: Array và Object.
Array dùng để lưu một danh sách dữ liệu.
const languages = [
'PHP',
'JavaScript',
'Python',
'Java'
];
console.log(languages[0]);
console.log(languages[1]);Kết quả:
PHP
JavaScriptArray sử dụng chỉ số bắt đầu từ 0.
Object dùng để lưu dữ liệu theo cặp khóa và giá trị.
const user = {
id: 1,
name: 'Pi',
email: 'pi@example.com',
role: 'user'
};
console.log(user.name);
console.log(user.email);Kết quả:
Pi
pi@example.comTrong thực tế, một danh sách thường chứa nhiều Object:
const users = [
{ id: 1, name: 'Pi', role: 'admin' },
{ id: 2, name: 'Hùng', role: 'user' },
{ id: 3, name: 'Chi', role: 'user' }
];Đây là cấu trúc dữ liệu rất phổ biến khi Laravel trả về danh sách người dùng hoặc bài viết dưới dạng JSON.
2. Khai báo và truy cập Array
2.1. Tạo Array
const posts = [
'Laravel 13',
'JavaScript',
'Vue'
];Lấy phần tử theo chỉ số:
console.log(posts[0]);
console.log(posts[1]);
console.log(posts[2]);Kết quả:
Laravel 13
JavaScript
Vue2.2. Lấy số lượng phần tử
Sử dụng thuộc tính length:
console.log(posts.length);Kết quả:
32.3. Thêm phần tử với push()
posts.push('React');
console.log(posts);Kết quả:
[
'Laravel 13',
'JavaScript',
'Vue',
'React'
]push() thêm phần tử vào cuối Array và thay đổi Array ban đầu.
2.4. Xóa phần tử cuối với pop()
posts.pop();
console.log(posts);pop() xóa và trả về phần tử cuối cùng.
2.5. Kiểm tra phần tử với includes()
const frameworks = ['Vue', 'React', 'Angular'];
console.log(frameworks.includes('Vue'));
console.log(frameworks.includes('Laravel'));Kết quả:
true
falseincludes() hữu ích khi cần kiểm tra một danh sách có chứa một giá trị hay không.
3. Duyệt Array với forEach()
Giả sử có danh sách bài viết:
const posts = [
{ id: 1, title: 'Laravel 13' },
{ id: 2, title: 'JavaScript' },
{ id: 3, title: 'Vue' }
];Duyệt bằng vòng lặp for:
for (let i = 0; i < posts.length; i++) {
console.log(posts[i].title);
}Có thể viết ngắn hơn bằng forEach():
posts.forEach(post => {
console.log(post.title);
});Kết quả:
Laravel 13
JavaScript
VueNếu cần chỉ số của phần tử:
posts.forEach((post, index) => {
console.log(index, post.title);
});Lưu ý: forEach() chủ yếu dùng để thực hiện một hành động với từng phần tử.
Nó không tạo ra Array mới và không chờ các hàm async bên trong hoàn thành.
4. map() — biến đổi dữ liệu
map() duyệt từng phần tử và trả về một Array mới chứa kết quả biến đổi.
Ví dụ:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2);
console.log(doubled);Kết quả:
[2, 4, 6, 8, 10]Array ban đầu không bị thay đổi:
console.log(numbers);Kết quả:
[1, 2, 3, 4, 5]Ứng dụng: lấy danh sách tiêu đề bài viết
const posts = [
{ id: 1, title: 'Laravel 13' },
{ id: 2, title: 'JavaScript' },
{ id: 3, title: 'Vue' }
];
const titles = posts.map(post => post.title);
console.log(titles);Kết quả:
['Laravel 13', 'JavaScript', 'Vue']Ứng dụng: định dạng dữ liệu từ API
const posts = [
{ id: 1, title: 'Laravel', views: 100 },
{ id: 2, title: 'Vue', views: 80 }
];
const formattedPosts = posts.map(post => ({
...post,
url: `/posts/${post.id}`
}));
console.log(formattedPosts);Kết quả sẽ là danh sách bài viết có thêm thuộc tính url.
Lưu ý dấu ngoặc đơn quanh Object trong Arrow Function: chúng giúp JavaScript hiểu rằng đây là Object được trả về, không phải phần thân hàm.
Ghi nhớ: dùng map() khi muốn biến đổi từng phần tử thành dữ liệu mới.
5. filter() — lọc dữ liệu
filter() tạo một Array mới chỉ chứa những phần tử thỏa mãn điều kiện.
Ví dụ:
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers);Kết quả:
[2, 4, 6]Ứng dụng: lọc bài viết đã xuất bản
const posts = [
{ id: 1, title: 'Laravel', status: 'published' },
{ id: 2, title: 'Vue', status: 'draft' },
{ id: 3, title: 'React', status: 'published' }
];
const publishedPosts = posts.filter(
post => post.status === 'published'
);
console.log(publishedPosts);Kết quả chứa bài viết Laravel và React.
Ứng dụng: lọc người dùng theo vai trò
const users = [
{ id: 1, name: 'Pi', role: 'admin' },
{ id: 2, name: 'Hùng', role: 'user' },
{ id: 3, name: 'Chi', role: 'admin' }
];
const admins = users.filter(user => user.role === 'admin');
console.log(admins);Ghi nhớ: filter() dùng để lọc danh sách, không xóa dữ liệu khỏi Array ban đầu.
Việc lọc ở JavaScript chỉ ảnh hưởng dữ liệu đang có trong trình duyệt. Nếu cần phân quyền hoặc bảo vệ dữ liệu, Laravel vẫn phải kiểm tra ở phía Server.
6. find() — tìm một phần tử
find() trả về phần tử đầu tiên thỏa mãn điều kiện. Nếu không tìm thấy, kết quả là undefined.
const users = [
{ id: 1, name: 'Pi' },
{ id: 2, name: 'Hùng' },
{ id: 3, name: 'Chi' }
];
const user = users.find(user => user.id === 2);
console.log(user);Kết quả:
{ id: 2, name: 'Hùng' }Nếu tìm ID không tồn tại:
const user = users.find(user => user.id === 99);
console.log(user);Kết quả:
undefinedỨng dụng: tìm bài viết cần hiển thị
const posts = [
{ id: 10, title: 'Laravel' },
{ id: 20, title: 'JavaScript' },
{ id: 30, title: 'Vue' }
];
const post = posts.find(post => post.id === 20);
console.log(post?.title);Kết quả:
JavaScriptDấu ?. giúp tránh lỗi khi không tìm thấy bài viết.
Phân biệt:
find()trả về một phần tử đầu tiên phù hợp.filter()trả về một Array chứa tất cả phần tử phù hợp.
7. some() và every() — kiểm tra điều kiện
7.1. some()
Trả về true nếu có ít nhất một phần tử thỏa mãn điều kiện.
const scores = [4, 6, 8, 9];
const hasExcellentScore = scores.some(score => score >= 9);
console.log(hasExcellentScore);Kết quả:
true7.2. every()
Trả về true nếu tất cả phần tử đều thỏa mãn điều kiện.
const scores = [7, 8, 9, 10];
const allPassed = scores.every(score => score >= 5);
console.log(allPassed);Kết quả:
trueỨng dụng với danh sách bài viết:
const posts = [
{ title: 'Laravel', published: true },
{ title: 'Vue', published: true }
];
console.log(posts.some(post => !post.published));
console.log(posts.every(post => post.published));Kết quả:
false
trueLưu ý: gọi some() hoặc every() trên Array rỗng sẽ lần lượt trả về false và true.
8. reduce() — tổng hợp dữ liệu
reduce() duyệt Array và tích lũy kết quả thành một giá trị.
Ví dụ tính tổng:
const prices = [100, 200, 300];
const total = prices.reduce((sum, price) => {
return sum + price;
}, 0);
console.log(total);Kết quả:
600Trong đó:
sum: giá trị tích lũy.price: phần tử đang xử lý.0: giá trị khởi tạo của bộ tích lũy.
Có thể viết ngắn hơn:
const total = prices.reduce((sum, price) => sum + price, 0);Ứng dụng: tính tổng lượt xem bài viết
const posts = [
{ title: 'Laravel', views: 100 },
{ title: 'Vue', views: 200 },
{ title: 'React', views: 150 }
];
const totalViews = posts.reduce(
(total, post) => total + post.views,
0
);
console.log(totalViews);Kết quả:
450Ứng dụng: thống kê bài viết theo trạng thái
const posts = [
{ status: 'published' },
{ status: 'draft' },
{ status: 'published' },
{ status: 'published' }
];
const statistics = posts.reduce((result, post) => {
result[post.status] = (result[post.status] ?? 0) + 1;
return result;
}, {});
console.log(statistics);Kết quả:
{
published: 3,
draft: 1
}reduce() rất mạnh, nhưng không cần sử dụng nó cho mọi việc. Nếu chỉ cần biến đổi danh sách, hãy dùng map(); nếu chỉ cần lọc, hãy dùng filter().
9. Sắp xếp dữ liệu với sort()
sort() sắp xếp các phần tử và thay đổi Array ban đầu.
Ví dụ sắp xếp số tăng dần:
const numbers = [40, 5, 100, 20];
numbers.sort((a, b) => a - b);
console.log(numbers);Kết quả:
[5, 20, 40, 100]Nếu viết numbers.sort() mà không có hàm so sánh, các số sẽ được sắp xếp theo thứ tự chuỗi, nên có thể cho kết quả không như mong muốn.
Sắp xếp bài viết theo lượt xem
const posts = [
{ title: 'Laravel', views: 100 },
{ title: 'Vue', views: 300 },
{ title: 'React', views: 200 }
];
const sortedPosts = [...posts].sort((a, b) => b.views - a.views);
console.log(sortedPosts);Kết quả: Vue, React, Laravel.
Ở đây, [...posts] tạo một bản sao nông trước khi sắp xếp để tránh thay đổi thứ tự của Array gốc.
10. Object — làm việc với dữ liệu có cấu trúc
10.1. Truy cập thuộc tính
const post = {
id: 1,
title: 'Laravel 13',
views: 100
};
console.log(post.title);
console.log(post['views']);
Cả hai cách đều hợp lệ.
10.2. Thêm và cập nhật thuộc tính
const post = {
id: 1,
title: 'Laravel'
};
post.views = 100;
post.title = 'Laravel 13';
console.log(post);10.3. Xóa thuộc tính
const user = {
name: 'Pi',
email: 'pi@example.com'
};
delete user.email;
console.log(user);delete xóa thuộc tính email khỏi Object hiện tại.
Nếu muốn giữ nguyên Object ban đầu, hãy tạo Object mới thay vì sửa trực tiếp.
10.4. Lấy danh sách khóa và giá trị
const user = {
name: 'Pi',
role: 'admin'
};
console.log(Object.keys(user));
console.log(Object.values(user));
console.log(Object.entries(user));Kết quả:
['name', 'role']
['Pi', 'admin']
[['name', 'Pi'], ['role', 'admin']]
Những phương thức này hữu ích khi cần kiểm tra, duyệt hoặc chuyển đổi dữ liệu Object.
11. Array chứa Object — cấu trúc thường gặp trong Laravel API
Giả sử Laravel trả về danh sách bài viết:
{
"data": [
{
"id": 1,
"title": "Laravel 13",
"status": "published",
"views": 120
},
{
"id": 2,
"title": "JavaScript",
"status": "draft",
"views": 50
},
{
"id": 3,
"title": "Vue",
"status": "published",
"views": 200
}
]
}
Khi dữ liệu đã được chuyển thành JavaScript Object, chúng ta có thể xử lý bằng các phương thức Array.
const responseData = {
data: [
{ id: 1, title: 'Laravel 13', status: 'published', views: 120 },
{ id: 2, title: 'JavaScript', status: 'draft', views: 50 },
{ id: 3, title: 'Vue', status: 'published', views: 200 }
]
};
const posts = responseData.data;
// Lấy danh sách tiêu đề.
const titles = posts.map(post => post.title);
// Lấy các bài đã xuất bản.
const publishedPosts = posts.filter(
post => post.status === 'published'
);
// Tìm bài viết có ID bằng 3.
const post = posts.find(post => post.id === 3);
// Tính tổng lượt xem.
const totalViews = posts.reduce(
(total, post) => total + post.views,
0
);
console.log(titles);
console.log(publishedPosts);
console.log(post);
console.log(totalViews);
Đây là những thao tác nền tảng khi xây dựng trang danh sách bài viết bằng JavaScript, Vue hoặc React.
12. Kết hợp tìm kiếm và lọc bài viết
Giả sử có danh sách:
const posts = [
{ id: 1, title: 'Laravel 13 cơ bản', category: 'Laravel' },
{ id: 2, title: 'JavaScript hiện đại', category: 'JavaScript' },
{ id: 3, title: 'Laravel REST API', category: 'Laravel' },
{ id: 4, title: 'Vue cơ bản', category: 'Vue' }
];
Tạo chức năng tìm kiếm:
const searchPosts = (posts, keyword) => {
const normalizedKeyword = keyword.trim().toLowerCase();
return posts.filter(post =>
post.title.toLowerCase().includes(normalizedKeyword)
);
};
console.log(searchPosts(posts, 'laravel'));Kết quả là hai bài viết có tiêu đề chứa từ laravel, không phân biệt chữ hoa và chữ thường.
Tiếp tục lọc theo danh mục:
const searchAndFilter = (posts, keyword, category) => {
const normalizedKeyword = keyword.trim().toLowerCase();
return posts.filter(post => {
const matchesKeyword = post.title
.toLowerCase()
.includes(normalizedKeyword);
const matchesCategory =
category === 'all' || post.category === category;
return matchesKeyword && matchesCategory;//phải thỏa cả title và category
});
};
console.log(searchAndFilter(posts, 'laravel', 'Laravel'));Đây là logic có thể tái sử dụng khi xây dựng chức năng Search & Filter trong các bài Vue sau này.
Với danh sách lớn, nên cân nhắc tìm kiếm và phân trang ở phía Laravel thay vì tải toàn bộ dữ liệu về trình duyệt.
13. Thực hành trong Laravel 13
Mục tiêu: hiển thị danh sách bài viết, tìm kiếm theo tiêu đề và tính tổng lượt xem.
Bước 1 — Tạo file JavaScript
Mở:
resources/js/app.js
Thêm code:
const posts = [
{ id: 1, title: 'Laravel 13', views: 120 },
{ id: 2, title: 'JavaScript hiện đại', views: 80 },
{ id: 3, title: 'Vue cơ bản', views: 200 },
{ id: 4, title: 'Laravel REST API', views: 150 }
];
const renderPosts = (items) => {
const list = document.querySelector('#postList');
if (!list) {
return;
}
list.replaceChildren();
items.forEach(post => {
const li = document.createElement('li');
const title = document.createElement('strong');
const views = document.createElement('span');
title.textContent = post.title;
views.textContent = ` — ${post.views} lượt xem`;
li.append(title, views);
list.append(li);
});
};
const searchInput = document.querySelector('#searchInput');
const totalViews = document.querySelector('#totalViews');
const updateTotalViews = (items) => {
const total = items.reduce(
(sum, post) => sum + post.views,
0
);
if (totalViews) {
totalViews.textContent = total;
}
};
if (searchInput) {
searchInput.addEventListener('input', () => {
const keyword = searchInput.value.trim().toLowerCase();
const filteredPosts = posts.filter(post =>
post.title.toLowerCase().includes(keyword)
);
renderPosts(filteredPosts);
updateTotalViews(filteredPosts);
});
}
renderPosts(posts);
updateTotalViews(posts);Bước 2 — Tạo Blade View
Tạo file:
resources/views/javascript.blade.php
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Array & Object - Laravel 13</title>
@vite(['resources/js/app.js'])
</head>
<body>
<h1>Quản lý bài viết</h1>
<label for="searchInput">Tìm kiếm bài viết:</label>
<input
type="search"
id="searchInput"
placeholder="Nhập tiêu đề..."
>
<h2>Danh sách</h2>
<ul id="postList"></ul>
<p>
Tổng lượt xem:
<strong id="totalViews">0</strong>
</p>
</body>
</html>Bước 3 — Khai báo Route
Mở routes/web.php:
use Illuminate\Support\Facades\Route;
Route::view('/javascript', 'javascript');Nếu file đã có khai báo Route, không cần import thêm lần nữa.
Bước 4 — Chạy ứng dụng
Nếu dự án Laravel của bạn đã cài Node dependencies:
npm run devMở terminal khác:
php artisan serveTruy cập:
http://127.0.0.1:8000/javascript
Thử nhập Laravel vào ô tìm kiếm.
Danh sách sẽ chỉ hiển thị những bài viết phù hợp và tổng lượt xem sẽ được tính lại.
Ví dụ này sử dụng dữ liệu giả lập để tập trung vào Array & Object.
Ở Bài 08, chúng ta sẽ thay dữ liệu này bằng dữ liệu nhận từ Laravel REST API.
14. Bài tập cuối bài
Bài 1 — Lọc sản phẩm
Cho dữ liệu:
const products = [
{ id: 1, name: 'Laptop', price: 15000000 },
{ id: 2, name: 'Mouse', price: 300000 },
{ id: 3, name: 'Keyboard', price: 800000 },
{ id: 4, name: 'Monitor', price: 4000000 }
];Hãy lọc các sản phẩm có giá lớn hơn hoặc bằng 1.000.000 đồng.
Bài 2 — Tìm người dùng
const users = [
{ id: 1, name: 'Pi', role: 'user' },
{ id: 2, name: 'Hùng', role: 'admin' },
{ id: 3, name: 'Chi', role: 'user' }
];Dùng find() để tìm người dùng có ID bằng 2.
Bài 3 — Tính tổng đơn hàng
const orders = [
{ id: 1, total: 100000 },
{ id: 2, total: 250000 },
{ id: 3, total: 150000 }
];Dùng reduce() để tính tổng giá trị các đơn hàng.
Bài 4 — Tìm kiếm bài viết
Cho danh sách bài viết ở phần 12.
Viết hàm tìm kiếm tiêu đề không phân biệt chữ hoa và chữ thường.
Bài 5 — Cập nhật Object
Cho dữ liệu:
const user = {
id: 1,
name: 'Pi',
role: 'user'
};Tạo một Object mới bằng Spread Operator, đổi role thành admin và giữ nguyên Object ban đầu.
15. Tổng kết
| Phương thức | Công dụng |
|---|---|
forEach() | Thực hiện hành động với từng phần tử |
map() | Biến đổi Array thành Array mới |
filter() | Lọc các phần tử thỏa mãn điều kiện |
find() | Tìm phần tử đầu tiên phù hợp |
some() | Kiểm tra có ít nhất một phần tử phù hợp |
every() | Kiểm tra tất cả phần tử có phù hợp |
reduce() | Tổng hợp dữ liệu thành một giá trị |
sort() | Sắp xếp Array |
Object.keys() | Lấy danh sách khóa |
Object.values() | Lấy danh sách giá trị |
Object.entries() | Lấy các cặp khóa và giá trị |
Điều quan trọng nhất không phải là thuộc lòng các phương thức, mà là biết chọn đúng công cụ cho từng công việc.
Muốn biến đổi dữ liệu: dùng
map().Muốn lọc danh sách: dùng
filter().Muốn tìm một phần tử: dùng
find().Muốn tính tổng: dùng
reduce().Muốn kiểm tra điều kiện: dùng
some()hoặcevery().
Đây là nền tảng xử lý dữ liệu mà chúng ta sẽ tiếp tục sử dụng khi gọi Laravel REST API, xây dựng danh sách bài viết bằng Vue và phát triển Blog SPA.
Bài 04 — Module & Import / Export: chia JavaScript thành nhiều file, tái sử dụng hàm và tổ chức code theo cấu trúc của một ứng dụng thực tế.
x1



Không có nhận xét nào:
Đăng nhận xét