객체의 순서를 보장하기
const obj = { "12": "c", "123": "a", "1": "b" };
console.log(Object.values(obj)); // c a b 가 아닌 b c a
왜 배열는 순서보장이 되고 객체는 순서보장이 되지 않을까?
배열은 인덱스 기반 자료구조라 순서보장이된다.
const arr = ["a", "b", "c"];
{
0: "a",
1: "b",
2: "c",
length: 3,
__proto__: Array.prototype
}
반면, 객체는 접근 자체가 중요한 자료구조라 순서를 따지지않도록 설계되었다. (해시 테이블)
{
"id" → hash("id") → 메모리 주소 0xABC
"name" → hash("name") → 메모리 주소 0x123
"email" → hash("email") → 메모리 주소 0x789
}
해시 함수가 주소를 결정한다.
키가 곧 주소가 되므로, 순서가 보장되지 않는 대신 O(1) 으로 접근이 가능하다.
그럼 어떻게 객체의 순서를 보장할 수 있을까?
정답은 Map 을 사용하면 된다.
Map 은 해시 테이블 + 연결 리스트로 구성된다.
hashTable: {
"name" → Node1의 주소
"age" → Node2의 주소
"city" → Node3의 주소
}
head ↔ Node1 ↔ Node2 ↔ Node3 ↔ tail
(name) (age) (city)
여전히 노드 주소를 가지므로 곧 바로 접근이 가능하다.
순서를 위한 추가 노드 속성이 필요하므로 추가 메모리가 필요하게 된다.
{
key: "name",
value: "Kim"
}
{
key: "name",
value: "Kim",
prev: 이전 노드 주소, // +8 bytes
next: 이후 노드 주소 // +8 bytes
}
연결 리스트 특성으로 순서를 보장하면서도 더 빠른 순회를 제공한다.