Đối tượng và cách tổ chức dữ liệu
Trong JavaScript, đối tượng (object) đóng vai trò là đơn vị cơ bản để nhóm và quản lý dữ liệu. Về mặt kỹ thuật, hầu hết các giá trị trong ngôn ngữ này đều có thể được xem xét dưới dạng object. Bản chất của một object là một tập hợp không sắp xếp thứ tự, được cấu thành từ nhiều cặp khóa-giá trị (key-value).
Cú pháp khai báo sử dụng dấu ngoặc nhọn {}. Mỗi thành phần bên trong bao gồm một định danh (khóa) và một giá trị tương ứng, được ngăn cách bởi dấu hai chấm :. Khi object chứa nhiều thành phần, các cặp sẽ được phân tách bằng dấu phẩy.
const appConfig = {
endpoint: "https://service.api/data",
retryCount: 3,
enableCache: true
};
Cốt lõi của Lập trình hướng đối tượng (OOP)
Khi làm việc với object, nhà phát triển chỉ cần tương tác thông qua các giao diện công khai mà không cần can thiệp vào cơ chế xử lý nội bộ. Phương pháp này mang lại ba nguyên lý nền tảng:
- Tính trừu tượng (Abstraction): Chuyển hóa các thực thể hoặc quy trình thực tế thành các thành phần lập trình. Mối quan hệ giữa các đối tượng thực tế sẽ được ánh xạ sang mã nguồn, giúp mô phỏng hệ thống một cách trực quan và dễ bảo trì.
- Tính đóng gói (Encapsulation): Ẩn giấu các logic triển khai phức tạp, chỉ để lộ ra những thao tác cần thiết cho bên ngoài gọi đến, qua đó giảm thiểu rủi ro can thiệp sai lệch.
- Tính kế thừa & Đa hình (Inheritance & Polymorphism): Cho phép xây dựng các phiên bản object mới dựa trên mẫu có sẵn, đồng thời hỗ trợ khả năng thực thi nhiều hình thái khác nhau cho cùng một giao diện hành vi.
Cấu trúc nội tại: Thuộc tính và Phương thức
Một object được xây dựng dựa trên hai thành tố chính:
- Thuộc tính (Property): Đại diện cho trạng thái hoặc dữ liệu lưu trữ của object tại một thời điểm.
- Phương thức (Method): Thể hiện hành vi hoặc chức năng xử lý mà object có thể thực hiện.
Nhiều lập trình viên thường nhầm lẫn giữa biến thông thường và thuộc tính object. Về cơ chế lưu trữ trong bộ nhớ, chúng hoạt động tương đồng, nhưng khác biệt rõ rệt về phạm vi sở hữu. Biến tồn tại độc lập trong ngữ cảnh hiện tại, trong khi thuộc tính luôn được gắn liền và quản lý bởi một object chủ.
Từ khóa this là công cụ quan trọng để xác định ngữ cảnh thực thi. Giá trị của this luôn trỏ trực tiếp đến object sở hữu phương thức đang được kích hoạt tại thời điểm đó, giúp code có thể tự động tham chiếu đến trạng thái hoặc phương thức khác của chính object đang chạy.
Ví dụ minh họa thực tế
Đoạn mã dưới đây làm rõ sự khác biệt giữa biến toàn cục, hàm độc lập, thuộc tính và phương thức khi thao tác với mảng (vốn là một dạng object đặc biệt trong JavaScript):
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<title>Thực hành Object trong JS</title>
</head>
<body>
<script>
document.addEventListener("DOMContentLoaded", () => {
// Mảng trong JS thực chất là object, có thể mở rộng bằng cách gán thêm thuộc tính
const dataset = [10, 25, 40, 55];
// Biến tự do: không thuộc về bất kỳ object nào, tồn tại trong scope hiện tại
const globalLimit = 50;
// Thuộc tính: được gắn trực tiếp vào object dataset
dataset.threshold = 100;
// Hàm tự do: tồn tại độc lập, không phụ thuộc vào ngữ cảnh object
const logStatus = () => {
console.log("Hàm độc lập đang chạy");
};
// Phương thức: thuộc về object dataset
// Từ khóa 'this' bên trong sẽ tự động trỏ về chính mảng dataset
dataset.analyze = function() {
console.log("Dữ liệu gốc:", this);
console.log("Ngưỡng tùy chỉnh:", this.threshold);
console.log("Độ dài mảng:", this.length);
};
// Kích hoạt phương thức để kiểm tra ngữ cảnh 'this'
dataset.analyze();
});
</script>
</body>
</html>