Kiểu dữ liệu tổng hợp (Composite/Reference Type) là kiểu chứa nhiều giá trị được nhóm lại. Trong JS, Object và Array là 2 kiểu tổng hợp chính. Bài này tập trung vào Object.
Object là gì?
Object là tập hợp các property (thuộc tính) dạng cặp key: value. Key là string hoặc Symbol, value là bất kỳ kiểu nào (primitive, object, function).
Cú pháp tạo Object
// Object literal (phổ biến nhất)
const person = {
name: "An",
age: 25,
isStudent: true,
address: { city: "Hanoi", zip: 100000 }, // Nested object
hobbies: ["reading", "coding"], // Array
greet() { console.log(`Hi, I'm ${this.name}`); } // Method (ES6 shorthand)
};
// Constructor function (cũ)
function Person(name, age) {
this.name = name;
this.age = age;
}
const p2 = new Person("Binh", 30);
// Object.create() (prototype-based)
const proto = { species: "Human" };
const p3 = Object.create(proto);
p3.name = "Cuong";
// Class (ES6 - syntactic sugar)
class PersonClass {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const p4 = new PersonClass("Dung", 28);
Truy cập property
| Cách | Cú pháp | Khi nào dùng |
|---|---|---|
| Dot notation | Key là identifier hợp lệ (chữ, số, _, $, không bắt đầu bằng số) | |
| Bracket notation | Key có khoảng trắng, ký tự đặc biệt, hoặc key là biến |
const obj = { "full name": "An", age: 25 };
obj.age; // 25 (dot)
obj["full name"]; // "An" (bracket - bắt buộc)
obj["age"]; // 25 (bracket cũng OK)
const key = "name";
obj[key]; // Bracket cho dynamic key
Thêm/Sửa/Xóa property
const user = { name: "An" };
// Thêm/Sửa
user.age = 25; // Thêm mới
user["email"] = "a@b.c"; // Thêm mới bằng bracket
user.name = "An Nguyen"; // Sửa
// Xóa
delete user.age; // true (xóa thành công)
delete user.nonexist; // true (không báo lỗi)
console.log(user.age); // undefined
Property Attributes (ES5)
Mỗi property có 4 attribute nội bộ (internal attributes):
[[Value]]: Giá trị dữ liệu[[Writable]]: Có gán lại được không[[Enumerable]]: Có xuất hiện trongfor...in,Object.keys()không[[Configurable]]: Có xóa được, đổi attribute không
Đọc/ghi bằng Object.getOwnPropertyDescriptor(), Object.defineProperty().
Getter & Setter (Accessor Properties)
const rect = {
width: 10,
height: 20,
get area() { return this.width * this.height; }, // Getter
set area(value) {
this.width = Math.sqrt(value);
this.height = Math.sqrt(value);
}
};
console.log(rect.area); // 200 (gọi getter như property)
rect.area = 100; // Gọi setter
console.log(rect.width); // 10
Kiểm tra property tồn tại
"prop" in obj; // true nếu có (kể cả prototype)
obj.hasOwnProperty("prop"); // true chỉ có own property
Object.prototype.hasOwnProperty.call(obj, "prop"); // An toàn hơn
Lưu ý
- Object là mutable – thay đổi ảnh hưởng tất cả tham chiếu.
- So sánh object:
obj1 === obj2chỉ true nếu cùng tham chiếu. - Dùng
constcho object – vẫn cho phép sửa property, chỉ cấm gán lại biến. - Shallow clone:
{...obj},Object.assign({}, obj). Deep clone:structuredClone(obj)(modern), lodashcloneDeep.