Trong JavaScript, object (đối tượng) là một kiểu dữ liệu quan trọng và linh hoạt. Ý nghĩa là 'đối tượng', nên việc thể hiện dữ liệu cũng sẽ thể hiện theo 'đối tượng'. Ứng dụng rất lớn trong việc lưu trữ thông tin như thông tin sinh viên, sản phẩm, v.v...
Giả sử ta muốn lưu một dữ liệu của một người với các thông tin: Tên, Tuổi, Nghề nghiệp
Có thể thấy các trường thông tin ở đây rất rõ ràng và của một đối tượng cụ thể vậy việc lưu trữ theo mảng, hay nhiều biến vẫn không thể đáp ứng được các yêu cầu này.
Cú pháp
Object bản chất cũng là một dữ liệu lưu trữ dữ liệu thông qua key - value. Để khởi tạo một object ta sẽ sử dụng cặp {}
Ví dụ:
const person = {};
Object lưu trữ dữ liệu thông qua key và value, cú pháp sẽ như sau:
Mỗi cặp key và value cách nhau bởi dấu ,(đối với key - value cuối cùng thì không cần thiết)
Như trên, ta có thể giải thích:
person là một dữ liệu object, có trường thông tin name, có giá trị là John; age là 30; job là Developer
Làm việc với object
Đối với object sẽ đơn giản hơn rất nhiều so với mảng, vì các thông tin đã được rõ ràng, ta chỉ việc 'chỉ định' trường thông tin ta cần, nếu thông tin đó không có, sẽ trả về undefined
Lấy giá trị của thuộc tính (key/property):
Để lấy giá trị của một thuốc tính, ta sẽ các cách như sau, cùng theo dõi ví dụ:
const person = {
name: "John",
age: 30,
job: "Developer"
};
// 'Chấm' tới thuộc tính cần lấy
console.log(person.name); // John
// Truyền tên thuộc tính cần lấy - bracket notation
console.log(person['name']);
// sử dụng cú pháp destructuring
const {name, age, job} = person;
Gán giá trị:
Truy xuất thuộc tính và gán lại giống như gán giá trị của mảng
const person = {
name: "John",
age: 30,
job: "Developer"
};
console.log(person.name); // John
person.name = 'Doraemon';
console.log(person.name); // Doraemon
Xoá key/property:
Để xoá một key trong object rất đơn giản, ta chỉ cần xác định key cần xoá và sử dụng cú pháp như sau:
delete object.key; // với object là đổi tượng muốn truy xuất, key là key cần xoá
const person = {
name: "John",
age: 30,
job: "Developer"
};
console.log(person.name); // John
delete person.name;
console.log(person.name); // undefined
Typescript với Object
Để định nghĩa kiểu dữ liệu object với Typescript, trước tiên ta sẽ tìm hiểu các khái niệm mới về Typescript
Interface
Interface trong TypeScript là một cách để định nghĩa cấu trúc của một đối tượng, giúp xác định các thuộc tính và phương thức mà một đối tượng phải có và chỉ có vậy (tức không thể tạo thêm các key ngoài interface).
Interface nên được sử dụng để định nghĩa kiểu cho object.
interface Person {
name: string;
age: number;
job: string;
}
// khai báo bắt buộc phải đầy đủ các key đã định nghĩa như interface Person
const person: Person = {
name: "John",
age: 30,
job: "Developer"
};
// trường hợp truy xuất một thuộc tính nào đó mà không được tính nghĩa từ interface sẽ bị lỗi
person.address // error
Xoákey với Typescript sẽ cần để ý một chút, xem hình ảnh dưới:
Ý nghĩa của interface khi định nghĩa, rằng các key là phải có, vậy thông báo lỗi nói rằng muốn xoá thì key nó phải là optional - có thể có, hoặc không. Để định nghĩa được một key là optional, tức có hoặc không đều được chấp thuận, trong định nghĩa, ta sẽ thêm dấu ?
interface Person {
// định nghĩa key name là optional
name?: string;
age: number;
job: string;
}
const person: Person = {
// khi khai báo không cần thêm key name
name: "John",
age: 30,
job: "Developer"
};
// lúc này delete key name đã hợp lệ
delete person.name;
Utility Record
Record là một trong các utility types (kiểu tiện ích) trong TypeScript, được sử dụng để tạo ra một kiểu đối tượng với một tập hợp các key và value cụ thể, thống nhất về kiểu dữ liệu.
Nó rất hữu ích khi muốn tạo một object có tập hợp các khóa và giá trị mà tất cả đều có chung một kiểu.
Duyệt object, ý nghĩa tương đối giống với duyệt mảng, mục tiêu là để duyệt qua từng các key có trong object. Giả sử bài toán như sau:
Cho thông tin đối tượng có: name - MindX; tuổi - 10; country - VietNam. Thực hiện in ra các thông tin của đối tượng trên.
for...in
for...in là một vòng lặp trong JavaScript cho bạn duyệt qua tất cả các thuộc tính (key/property) của một đối tượng (object). Nó rất hữu ích khi muốn truy cập từng key của một đối tượng và có thể lấy giá trị tương ứng của từng key đó.
Cú pháp:
for (let key in object) {
// Thực hiện các thao tác với key và object[key]
}
key - biến đại diện cho các key của object đang duyệt.
object - là đối tượng muốn duyệt.
Muốn lấy được giá trị qua key trường hợp này, bắt buộc phải sử dụng cú pháp object[key]Do key lúc này là biến.
Ví dụ:
Javascript
const person = {
name: 'MindX',
age: 10,
country: 'VietNam'
}
for (let key in person) {
console.log(key + ": " + person[key]);
}
Typescript
Đoạn code phía dưới tưởng như hợp ý, nhưng sẽ bị lỗi:
interface Person {
name: string,
age: number,
country: string
}
const person: Person = {
name: 'MindX',
age: 10,
country: 'VietNam'
}
for (let key in person) {
console.log(key + ": " + person[key]);
}
Lỗi này ở đây, do biến key trong vòng lặp chưa được khai báo kiểu dữ liệu, nên TS không nhận diện được rằng key thuộc vào phạm vi dữ liệu key mà Person đã được định nghĩa và chắc chắn, không có cách nào khai báo được kiểu dữ liệu cho key trong vòng lặp for...in
Ta chỉ có cách thực hiện chuyển đổi kiểu (chuyển đổi kiểu không phải ép kiểu) cho key với cú pháp như sau:
interface Person {
name: string,
age: number,
country: string
}
const person: Person = {
name: 'MindX',
age: 10,
country: 'VietNam'
}
for (let key in person) {
// thực hiển chuyển đổi kiểu key sang các key hợp lệ của interface Person sử dụng từ khoá as
// keyof ... thực hiện lấy các kiểu key của kiểu dữ liệu đối tượng
console.log(key + ": " + person[key as keyof Person]);
}
Kết hợp Object và Array
Trong lưu trữ thông tin, việc Array và Object kết hợp, tạo ra các cấu trúc dữ liệu phục vụ cho quản trị dữ liệu, phân tích dữ liệu, v.v..
Ví dụ đơn giản, cho một danh sách sản phẩm, với mỗi sản phẩm có thông tin như sau: tên, giá, mô tả, số lượng. Khi nhận được yêu cầu này, ta nhận thấy có 2 cấu trúc cần phải sử dụng:
Danh sách - sử dụng mảng (array)
Sản phẩm - đối tượng (object)
Danh sách sản phẩm, tức mỗi sản phẩm sẽ phải thuộc trong danh sách, vậy theo ý nghĩa dữ liệu, mỗi phần tử của mảng, sẽ là một object.
Theo dõi ví dụ dưới đây và dành ra 1 phút để phân tích, suy nghĩ để hiểu hơn:
Javascript
const techProducts = [
{
name: "Laptop Dell XPS 13",
price: 1500,
description: "Laptop mỏng nhẹ với màn hình 13.4 inch, vi xử lý Intel Core i7 thế hệ 11 và ổ cứng SSD 512GB.",
quantity: 10
},
{
name: "Apple iPhone 13 Pro",
price: 1200,
description: "Điện thoại iPhone 13 Pro với màn hình Super Retina XDR 6.1 inch, chip A15 Bionic và hệ thống camera ba ống kính.",
quantity: 25
},
{
name: "Tai nghe Sony WH-1000XM4",
price: 350,
description: "Tai nghe chống ồn chủ động cao cấp từ Sony, với thời lượng pin lên đến 30 giờ và khả năng kết nối không dây Bluetooth.",
quantity: 15
},
{
name: "Apple Watch Series 7",
price: 500,
description: "Đồng hồ thông minh với màn hình lớn hơn, chống nước và theo dõi sức khỏe toàn diện.",
quantity: 30
},
{
name: "Máy tính bảng Samsung Galaxy Tab S7",
price: 700,
description: "Máy tính bảng với màn hình 11 inch, hỗ trợ bút S Pen, chạy hệ điều hành Android 11.",
quantity: 20
},
{
name: "Loa thông minh Google Nest Audio",
price: 100,
description: "Loa thông minh tích hợp trợ lý ảo Google Assistant, âm thanh sống động và kết nối với hệ thống nhà thông minh.",
quantity: 50
},
{
name: "Camera GoPro HERO9",
price: 450,
description: "Camera hành trình GoPro HERO9 với khả năng quay video 5K, chống nước và ổn định hình ảnh mạnh mẽ.",
quantity: 12
},
{
name: "Bàn phím cơ Keychron K2",
price: 80,
description: "Bàn phím cơ không dây với layout 75%, hỗ trợ kết nối đa thiết bị và các phím chuyển đổi Mac/Windows.",
quantity: 40
}
];
console.log(techProducts);
Typescript
interface Product {
name: string;
price: number;
description: string;
quantity: number;
}
const techProducts: Product[] = [
{
name: "Laptop Dell XPS 13",
price: 1500,
description: "Laptop mỏng nhẹ với màn hình 13.4 inch, vi xử lý Intel Core i7 thế hệ 11 và ổ cứng SSD 512GB.",
quantity: 10
},
{
name: "Apple iPhone 13 Pro",
price: 1200,
description: "Điện thoại iPhone 13 Pro với màn hình Super Retina XDR 6.1 inch, chip A15 Bionic và hệ thống camera ba ống kính.",
quantity: 25
},
{
name: "Tai nghe Sony WH-1000XM4",
price: 350,
description: "Tai nghe chống ồn chủ động cao cấp từ Sony, với thời lượng pin lên đến 30 giờ và khả năng kết nối không dây Bluetooth.",
quantity: 15
},
{
name: "Apple Watch Series 7",
price: 500,
description: "Đồng hồ thông minh với màn hình lớn hơn, chống nước và theo dõi sức khỏe toàn diện.",
quantity: 30
},
{
name: "Máy tính bảng Samsung Galaxy Tab S7",
price: 700,
description: "Máy tính bảng với màn hình 11 inch, hỗ trợ bút S Pen, chạy hệ điều hành Android 11.",
quantity: 20
},
{
name: "Loa thông minh Google Nest Audio",
price: 100,
description: "Loa thông minh tích hợp trợ lý ảo Google Assistant, âm thanh sống động và kết nối với hệ thống nhà thông minh.",
quantity: 50
},
{
name: "Camera GoPro HERO9",
price: 450,
description: "Camera hành trình GoPro HERO9 với khả năng quay video 5K, chống nước và ổn định hình ảnh mạnh mẽ.",
quantity: 12
},
{
name: "Bàn phím cơ Keychron K2",
price: 80,
description: "Bàn phím cơ không dây với layout 75%, hỗ trợ kết nối đa thiết bị và các phím chuyển đổi Mac/Windows.",
quantity: 40
}
];
console.log(techProducts);
Một số bài toán cơ bản liên quan:
Thêm mới thông tin sản phẩm
Tìm kiếm sản phẩm
Xoá sản phẩm
Cập nhật thông tin sản phẩm
Tất cả các bài toán đều xoay quanh 4 bài toán: CRUD
Create
Read
Update
Delete
Object là kiểu dữ liệu rất đáng giá trong việc sử dụng thể hiện cấu trúc dữ liệu, khi kết hợp với Mảng, lại càng thể hiện được tính chất của hệ thống hơn. Hãy thành thạo và rèn luyện việc kết hợp giữa Mảng và Object.