JavaScript로 작성된 Map 80/20 안내서
본문
JavaScript에서 Map은 키/값 쌍을 저장하는 객체입니다. Map는 일반적인 자바스크립트 객체와 비슷하지만 객체와 Map간에 유용한 몇 가지 주요 차이점이 있습니다.
http://thecodebarbarian.com/the-80-20-guide-to-maps-in-javascript.html
Maps vs Objects
일부 키/값 경로를 저장하는 JavaScript 객체를 생성한다고 가정합니다. 아래와 같이 일반 오래된 JavaScript 객체 또는 "POJO"를 간단히 정의 할 수 있습니다.
const obj = {
name: 'Jean-Luc Picard',
age: 59,
rank: 'Captain'
};
obj.name; // 'Jean-Luc Picard'
아래에 표시된 것과 동일한 키와 값을 포함하는 맵을 정의 할 수도 있습니다.
const map = new Map([
// You define a map via an array of 2-element arrays. The first
// element of each nested array is the key, and the 2nd is the value
['name', 'Jean-Luc Picard'],
['age', 59],
['rank', 'Captain']
]);
// To get the value associated with a given `key` in a map, you
// need to call `map.get(key)`. Using `map.key` will **not** work.
map.get('name'); // 'Jean-Luc Picard'
피카드 선장의 나이를 원한다고 가정 해 봅시다. 객체와 함께 obj.age를 사용할 수 있습니다. 지도에서는 map.get ( 'age')를 사용합니다. 내장 JavaScript 기능과 충돌하지 않는 속성에는 적합하지만 객체의 생성자 속성을 얻으려면 어떻습니까? 이 경우 obj.constructor가 정의되지만 map.get ( 'constructor')는 정의되지 않습니다.
obj.constructor; // [Function: Object]
map.get('constructor'); // undefined
Maps에는 상속에 대한 개념이 없습니다. Maps에는 상속 된 키가 없습니다. 따라서 기존 방법 및 속성과 충돌하는 데이터에 대해 걱정할 필요 없이 원시 데이터를 저장하는 데 이상적입니다. 예를 들어, Maps는 프로토 타입 오염에 영향을 받지 않습니다. 사용자 데이터를 순식간에 복사하면 악의적인 사용자가 클래스 메서드를 덮어 쓸 수 있는 보안 취약점이 있습니다.
또 다른 주요 차이점은 맵을 사용하면 문자열 뿐만 아니라 객체 키를 저장할 수 있다는 것입니다. 날짜 또는 숫자와 같은 객체를 키로 저장할 때 약간의 혼란이 발생할 수 있습니다.
const map = new Map([]);
const n1 = new Number(5);
const n2 = new Number(5);
map.set(n1, 'One');
map.set(n2, 'Two');
// `n1` and `n2` are objects, so `n1 !== n2`. That means the map has
// separate keys for `n1` and `n2`.
map.get(n1); // 'One'
map.get(n2); // 'Two'
map.get(5); // undefined
// If you were to do this with an object, `n2` would overwrite `n1`
const obj = {};
obj[n1] = 'One';
obj[n2] = 'Two';
obj[n1]; // 'Two'
obj[5]; // 'Two'
Maps에는 Maps의 키/값 쌍 수를 반환하는 size 속성도 있습니다. 객체의 키 수를 얻으려면 Object.keys(obj) .length를 수행해야 합니다.
map.size; // 3
또 다른 차이점은 맵의 키 순서가 보장된다는 것입니다. 즉, map.keys()를 호출하면 항상 키가 맵에 추가 된 순서대로 가져옵니다. Captain Picard 예에서 map.keys()는 항상 이름, 나이 및 순위를 순서대로 반환합니다.
ES6 호환 브라우저에서도 객체 키 순서가 보장됩니다. 예를 들어 Object.keys(obj)는 ES6 호환 JavaScript 런타임에서 항상 [ 'name', 'age', 'rank']를 반환합니다. 그러나 이전 런타임 (Internet Explorer 등)에서는 Object.keys(obj)가 다른 순서로 키를 반환 할 수 있습니다.
Map#keys(), Map#values(), Map#entries()
Maps에는 Maps를 반복하는 세 가지 기본 메소드인 keys(), values() 및 entries()가 있습니다. Object.keys()와 달리 Map#keys() 함수는 배열이 아닌 iterator를 반환합니다. 즉, Maps의 키를 반복하는 가장 쉬운 방법은 for/of loop를 사용하는 것입니다.
const map = new Map([
['name', 'Jean-Luc Picard'],
['age', 59],
['rank', 'Captain']
]);
const iterator = map.keys();
console.log(iterator); // MapIterator { 'name', 'age', 'rank' }
// `map.keys()` returns an iterator, not an array, so you can't
// access the values using `[]`
iterator[0]; // undefined
// The `for/of` loop can loop through iterators
for (const key of map.keys()) {
key; // 'name', 'age', 'rank'
}
때로는 iterator를 배열로 변환하는 것이 편리하므로 filter() 및 map()과 같은 배열 메서드를 사용할 수 있습니다. iterator를 배열로 변환하는 가장 쉬운 방법은 내장 Array.from() 함수를 사용하는 것입니다.
const arr = Array.from(map.keys());
arr.length; // 3
arr[0]; // 'name'
arr[1]; // 'age'
arr[2]; // 'rank'
Map#values() 함수는 iterator를 반환합니다. iterator는 맵의 값을 반복합니다.
for (const v of map.values()) {
v; // 'Jean-Luc Picard', 59, 'Captain'
}
마지막으로 Map # entries()는 Map 생성자와 비슷한 형식으로 맵의 키/값 쌍을 반복하는 iterator를 반환합니다. Map#entries() 함수는 Map 클래스와 Object.entries()에 해당합니다.
for (const [key, value] of map.entries()) {
key; // 'name', 'age', 'rank'
value; // 'Jean-Luc Picard', 59, 'Captain'
}
Map#entries() 함수를 사용하면 map를 쉽게 복사 할 수 있습니다. map를 복제하는 것은 map.entries()를 배열로 변환하는 것만큼 간단합니다.
// `clone` is now a separate map that contains the same keys/values
// as `map`.
const clone = new Map(Array.from(map.entries()));
계속
JavaScript 개발자는 일반적으로 객체를 사용하여 사용자 데이터를 저장하지만 Maps에는 몇 가지 장점이 있습니다. 프로토 타입 오염 또는 JSON 데이터 덮어 쓰기 클래스 메소드의 위험이 없습니다. Maps을 사용하면 객체 키를 저장할 수 있습니다. 이는 symbol을 설정하지 않고 데이터를 객체와 연결하려는 경우 유용 할 수 있습니다. 오픈 소스 JavaScript에서는 Maps이 여전히 흔하지 않습니다. 내가 본 유일한 사용 사례는 몽구스의 Maps 유형입니다. 그러나 Maps은 프로토 타입 오염의 위험을 피하기 때문에 JSON 데이터를 표현하기 위해 실험 해 볼 가치가 있습니다.
- 이전글JavaScript 이터레이터 및 생성기 : 동기식 이터레이터 19.10.12
- 다음글왜 0.1 + 0.2 === 0.30000000000000004 : JS에서 IEEE 754 구현 19.10.12