Trong JavaScript, Object và Map (ES6) đóng vai trò Dictionary (Key-Value store). Tìm kiếm key rất nhanh O(1) trung bình nhờ Hash Table bên dưới.
1. Triển khai custom Dictionary (MyMap) - Có phương thức get()
class MyMap {
constructor() {
this.container = {}; // Dùng Object làm backend
}
// Kiểm tra key tồn tại
hasKey(key) {
return key in this.container; // Hoặc this.container.hasOwnProperty(key)
}
// Tìm kiếm (Get)
get(key) {
if (this.hasKey(key)) {
return this.container[key];
}
return undefined; // Không tìm thấy
}
// Thêm/Sửa
put(key, value) {
this.container[key] = value;
}
// Xóa
delete(key) {
if (this.hasKey(key)) {
delete this.container[key];
return true;
}
return false;
}
display() {
console.log(this.container);
}
}
// Test
const myMap = new MyMap();
myMap.put("key1", "value1");
myMap.put("key2", "value2");
console.log(myMap.get("key1")); // "value1"
console.log(myMap.get("key2")); // "value2"
console.log(myMap.get("key3")); // undefined
2. ES6 Map (Khuyên dùng cho Production)
Map là cấu trúc dữ liệu Dictionary chuẩn, hiệu năng tốt hơn Object cho thêm/xóa nhiều, key kiểu bất kỳ, thứ tự insertion order.
const myMap = new Map([
["key1", "value1"],
["key2", "value2"]
]);
// Tìm kiếm - O(1)
console.log(myMap.get("key1")); // "value1"
console.log(myMap.get("key2")); // "value2"
console.log(myMap.get("key3")); // undefined
// Kiểm tra tồn tại
console.log(myMap.has("key1")); // true
console.log(myMap.has("key3")); // false
// Thêm/Sửa
myMap.set("key3", "value3");
// Xóa
myMap.delete("key2");
console.log(myMap.has("key2")); // false
// Kích thước
console.log(myMap.size); // 2
// Duyệt
myMap.forEach((value, key) => console.log(key, value));
for (const [key, value] of myMap) console.log(key, value);
3. Object thuần (Legacy / Simple Cases)
const dict = {
key1: "value1",
key2: "value2"
};
// Tìm kiếm
console.log(dict["key1"]); // "value1" (Bracket notation - key biến số)
console.log(dict.key1); // "value1" (Dot notation - key cố định)
console.log(dict.key3); // undefined
// Kiểm tra tồn tại (Phân biệt undefined value vs key không tồn tại)
console.log("key1" in dict); // true
console.log(dict.hasOwnProperty("key1")); // true (chỉ own property)
console.log("key3" in dict); // false
So sánh Object vs Map cho Dictionary
| Đặc điểm | Object | Map (ES6) |
|---|---|---|
| Key type | String / Symbol | Bất kỳ (Object, Function, Primitive...) |
| Kích thước | Không có .size (Object.keys().length) | .size |
| Thứ tự | ES2015+ giữ insertion order (string key) | Luôn giữ insertion order |
| Hiệu năng thêm/xóa nhiều | Chậm hơn | Nhanh hơn, tối ưu |
| Prototype pollution | Có rủi ro (__proto__, toString) | An toàn (không prototype) |
| JSON Serialize | JSON.stringify trực tiếp | Cần convert: Array.from(map) hoặc [...map] |
| Iterable | Không trực tiếp (Object.keys/values/entries) | ✅ Trực tiếp for...of |
Best Practice
- Dùng Map cho Dictionary chung, dữ liệu động, key không phải string, hiệu năng quan trọng.
- Dùng Object cho record cấu trúc cố định (schema), config, DTO, cần JSON.stringify trực tiếp.
- Luôn dùng
map.has(key)/key in obj/obj.hasOwnProperty(key)để check tồn tại, tránh nhầmundefinedvalue.
Tóm lại: Tìm kiếm Dictionary JS: map.get(key) (Map ES6) hoặc obj[key] (Object). Kiểm tra tồn tại: map.has(key) / key in obj. Ưu tiên Map cho Dictionary động, hiệu năng cao.