배열 연산 시 원본을 조작하지 않아야 되는데 그런 조작은 예상치 못한 결과를 낳을 수 있다. 조작이 항상 문제를 일으키는 것은 아니지만 잠재적으로 문제가 되므로 피하는 것이 좋다.
배열을 조작하기 위해 흔히 사용하는 push() 메서드를 보면 새로운 항목을 배열 뒤에 추가해 원본 배열을 변경한다. 즉, 항목을 추가하면 원본 배열을 조작하는 셈이다.
다행히 펼침 연산자를 이용하면 원본 배열이 조작되는 부수 효과를 방지할 수 있다.
다음 예제를 보면
const cart = [
{
name: 'a',
pricec: 20.0,
discount: false,
},
{
name: 'b',
pricec: 18.2,
discount: false,
},
{
name: 'c',
pricec: 24.0,
discount: true,
},
];
const reward = {
name: 'd',
discount: true,
price: 0,
};
function addFreeGift(cart){
if(cart.length > 2){
cart.push(reward);
return cart;
}
return cart;
}
function summarizeCart(cart){
const discountalbe = cart.filter(item => item.discount);
if(discountable.length > 1){
return {
error: '할인 상품은 하나만 주문할 수 있습니다.',
};
}
const cartWithReward = addFreeGift(cart);
return {
discounts: discountalbe.length,
items: cartWithReward.length,
cart: cartWithReward
}
}
할인 금액을 확인하고 할인 상품이 두 개 이상이면 오류 객체를 반환하고 오류가 없다면 상품을 많이 구매한 사람에게 사은품을 주는 예제이다.
이 코드는 이상이 없으나
function summarizeCart(cart){
const cartWithReward = addFreeGift(cart);
const discountalbe = cart.filter(item => item.discount);
if(discountable.length > 1){
return {
error: '할인 상품은 하나만 주문할 수 있습니다.',
};
}
return {
discounts: discountalbe.length,
items: cartWithReward.length,
cart: cartWithReward
}
}
summarizeCart함수를 정리하려고 모든 변수를 함수의 상단으로 옮기면 분리된 함수에서 의도치 않게 배열의 원본을 조작하기 때문에 문제가 발생한다.
즉, 함수를 호출할 때는 함수에 전달한 값을 변경하지 않을 것이라는 신뢰가 필요하다.
부수 효과가 없는 함수를 순수 함수라고 하며, 우리는 순수 함수를 만들기 위해 노력해야 한다.
그래서 앞의 원본 배열이 변경되는 문제를 해결하기 위해서 펼침 연산자를 사용하면 된다.
function addFreeGift(cart) {
if (cart.length > 2) {
cart.push(reward);
return [...cart, reward];
}
return cart;
}
function summarizeCart(cart) {
const cartWithReward = addFreeGift(cart);
const discountalbe = cart.filter((item) => item.discount);
if (discountable.length > 1) {
return {
error: '할인 상품은 하나만 주문할 수 있습니다.',
};
}
return {
discounts: discountalbe.length,
items: cartWithReward.length,
cart: cartWithReward,
};
}
결과적으로 내용을 목록에 다시 쓰기만 하면 새로운 배열을 생성하므로 원본 배열을 변경할 가능성이 전혀 없다.
원본 배열의 내용만 재사용해 새로운 배열을 만드는 것이다.
펼침 연산자로 배열을 만드는 방식의 장점은 수많은 메서드를 잊어버려도 좋다는 점이다.
배열의 시작 부분에 새로운 항목을 추가하거나 배열의 사본을 만들 때 역시 펼침 연산자를 이용할 수 있다.
// 배열의 앞에 추가하기
const titles = ['hi', 'bye'];
const titles2 = ['good',...titles];
//복사하기
const copies = ['c', 'd'];
const copied = [...copies];
'Javascript > 자바스크립트 코딩의 기술' 카테고리의 다른 글
9. 펼침 연산자로 정렬에 의한 혼란을 피하기 (0) | 2021.02.06 |
---|---|
7. 펼침 연산자로 배열을 본떠라 (0) | 2021.01.27 |
6. Includes()로 존재 여부를 확인하기 (0) | 2021.01.26 |
5. 배열로 유연한 컬렉션 생성하기 (0) | 2021.01.25 |
4. 템플릿 리터럴로 변수를 읽을 수 있는 문자열로 변환하기 (0) | 2021.01.24 |