7. 객체 펼침 연산자를 이용한 정보 갱신
앞서 공부한 Object.assign() 메서드의 장점을 객체 펼침 연산자의 문법으로 대체해보자.
객체 펼침 연산자의 동작은 키-값 쌍을 목록에 있는 것처럼 반환한다. 이로인해, 펼침 연산자 앞 뒤에 쉽게 새로운 정보를 추가할 수 있다. 또한, 독립적으로 사용이 불가하다.
배열 펼침 연산자와 다른점은 같은 키에 서로 다른 값을 선언하면 가장 마지막에 선언된 값을 사용한다.
(배열 펼침연산자는 서로 다른 값을 선언한다면 선언한 값이 모두 선언됨)
const book1 = {
title: `Reasons and Persons`,
author: `Derek Parfit`,
};
const update2 = { ...book1, title: `Reasons & Person` };
// { title: 'Reasons & Persons', author: 'Derek Parfit' }
한번 Object.assign()과 객체 펼침 연산자을 비교해보자. 아래는 Object.assign()을 사용한 코드이다.
const defaults = {
author: ``,
title: ``,
year: 2017,
rating: null,
};
const book2 = {
author: `Joe Morgan`,
title: `Simplifing JavaScript`,
};
const update3 = Object.assign({}, defaults, book2);
// { author: `Joe Morgan`, title: 'Simplifing JavaScript', year: 2017, rating: null}
const update4 = { ...defaults, ...book2 };
// { author: `Joe Morgan`, title: 'Simplifing JavaScript', year: 2017, rating: null}
펼침 연산자를 이용하면 더 쉽게 추가로 선언할 수 있다. 하지만 앞에서도 깊은 병합 문제는 펼침 연산자를 이용해도 발생한다. 이 때, 중첩된 객체를 복사하지 않고 참조만 복사하기에 조작으로 인해 잠재적으로 문재를 만든다.
해결 방법을 아래의 코드를 통해 보도록하자.
const defaults2 = {
author: `Joe Morgan`,
title: `Simplifying Javascript`,
spec: {
year: null,
},
};
const bookSpec1 = {
spec: {
year: 2017,
},
};
const updateByOb = Object.assign(
{},
defaults2,
{
spec: Object.assign({}, bookSpec1.spec),
},
);
const updateBySP = {
...defaults2,
spec: { ...bookSpec2.spec },
};
이처럼, 깊은 병합 또한 객체 펼침 연산자를 이용하여 해결할 수 있다.
객체 펼침 연산자의 장점은 1-새로운 객체 생성의 의도를 명확히 전달가능 2-빈객체로 시작하는 것을 안해도됨 이라고 생각한다.
8. 맵으로 명확히 키-값 정보를 갱신하라
앞에서 정보의 갱신이 자주 이러나는 상황에서는 맵을 활용하는게 좋다고 말했다.
맵은 키-값이 자주 추가되거나 삭제되는 경우, 키가 문자열이 아닌 경우 등에서 사용된다.
우선 키-값이 자주 추가되거나 삭제되는 상황에서 사용하는 것을 보자.
const dogs = [ //강아지 컬랙션(배열)
{
이름: `맥스`,
크기: `소형견`,
견종: `보스턴테리어`,
색상: `검정색`,
},
{
이름: `도니`,
크기: `대형견`,
견종: `래브라도레트리버`,
색상: `검정색`,
},
{
이름: `섀도`,
크기: `중형견`,
견종: `래브라도레트리버`,
색상: `갈색`,
},
];
let filters1 = {}; //새로운 정보를 담을 빈 객체
//조건 추가 함수
function addFilters(filters, key, value) {
filters[key] = value;
}
//필터링 조건 삭제
function deleteFilters(filters, key) {
delete filters[key];
}
//모든 조건 제거
function vlearFilters(filters) {
filters = {};
return filters;
}
이렇게 배열로 구성된 콜랙터를 이용해 갱신하는 코드가 있다. 거기다 조건 추가, 삭제, 제거 3가지 패러다임을 갖는다.
맵은 키-값이 자주 변경되는 상황에 접합하다. 인터페이스가 명확하고, 메서드는 예측 가능한 이름을 갖고, 반복과 같은 동작은 내장되있다. 또한 맵은 좀 더 특화된 컬렉션이므로 JS 엔진 개발자들은 코드가 좀 더 빠르게 동작하도록 최적화할 수 있습니다. 이제 예시 코드를 보도록 하자.
//맵에서는 항상 명시적으로 새로운 인스턴스를 생성해야 한다.
let filters2 = new Map();
//set()메서드를 통해 데이터를 추가
filters2.set(`견종`, `래브라도레트리버`);
//데이터를 가져오려면 get()메서드 이용
filters2.get(`견종`);
//set(key, value) get(key)
console.log(filters2.get(`견종`));
//체이닝(chaining)을 이용하여 새로운 인스턴스 생성후 바로 메서드 연결
let filters3 = new Map()
.set(`견종`, `래브라도레트리버`)
.set(`크기`, `대형견`)
.set(`색상`, `갈색`);
console.log(filters3.get(`크기`));
//배열을 이용한 정보 추가
let filters4 = new Map(
[
[`견종`, `래브라도레트리버`],
[`크기`, `대형견`],
[`색상`, `흰색`],
]
)
총 3가지 맵을 생성하는 방법을 작성했다. 데이터 추가는 .set() , 데이터를 가저오는 .get() , 데이터를 삭제하는 .delete() , 키-값 쌍으로 제거할때 사용하는 .clear() 를 사용하여 Map을 활용할 수 있다.
그렇다면 여기서 나온 메서드를 이용하여 맵을 사용하여 함수를 변경해보자.
const petFilters = new Map();
function addFilters(filters, key, value) {
filters.set(key, value);
}
function deleteFilters(filters, key) {
filters.delete(key);
}
function clearFilters(filters) {
filters.clear();
}
addFilters(petFilters, `색상`, `검정`);
addFilters(petFilters, `견종`, `말티푸`);
deleteFilters(petFilters, `견종`);
clearFilters(petFilters);
이렇게 사용한다면 변경사항은 많이 없지만, 장점이 있다.
1️⃣코드가 훨씬 명료하게 보인다. 2️⃣맵 인스턴스에 항상 메서드를 사용한다. 3️⃣delete()사용이 가능하기에 인스턴스 생성 후 언어수준의 연산자를 섞지 않음. 4️⃣clear() 사용이 가능하기에 새로운 인스턴스를 생성할 필요가 없음.
⭕객체와는 달리 정수를 키(key)로 사용할 수 있다. 이때 map의 keys를 반환하면 맵이터레이터라는 값이 반환된다.
이를 이용해 데이터를 순회할 수 있다.
❗❗객체 사용의 경우 정수를 키(key)로 사용할 수 없다. 점표기법으로 접근이 불가능하고 배열표기법으로는 접근이 가능하다. 오류코드 객체를 생성했을 때 모든 정수가 문자열로 변환됐기 때문이다. 그리고 열 표기법을 사용하면 탐색에 앞서 정수가 문자열로 변경된다.
오늘도
Just 두 IT!!!