티스토리 뷰
Tip 7. 펼침 연산자로 배열을 본떠라
* 배열은 수많은 메서드가 있으므로 혼란스럽거나 조작과 부수 효과로 인한 문제가 생길 수 있다.
const cart = ['abc', 'cdf'];
const copyCart = [...cart]; //['abc', 'cdf']
=> 새로운 배열을 선언하고 펼침 연산자로 배열의 전체 요소를 가져올 수 있다.
function removeItem(items, removable) {
const updated = [];
for (let i = 0; i < items.length; i++) {
if (items[i] !== removable) {
updated.push(items[i]);
}
}
return updated;
}
=> items 배열의 길이만큼 반복한다. items 배열의 요소들 중 removable과 일치하지 않는 요소는 updated 배열에 넣는다.
=> 반복하고 조건문에 따라 updated 배열을 반환한다.
function removeItem(items, removable) {
if (items.includes(removable)) {
const index = items.indexOf(removable);
items.splice(index, 1);
}
return items;
}
=> 시작 index에서 요소 하나만 제거한다.
const books = ['practical vim', 'moby dick', 'the dark tower'];
const recent = removeItem(books, 'moby dick');
const novels = removeItem(books, 'practical vim');
=> recent에서는 moby dick을 제거한 배열이 만들어진다.
=> novels에서는 moby dick을 제거한 배열을 이어받아 the dark tower, practical vim 배열이 만들어진다. 원본 배열 books가 함수를 거듭 사용함에 따라 조작되었다.
=> slice(): 원본 배열을 변경하지 않고 배열의 일부를 반환.
function removeItem(items, removable) {
if (items.includes(removable)) {
const index = items.indexOf(removable);
return items.slice(0, index).concat(items.slice(index + 1));
}
return items;
}
=> concat()으로 배열 두 개를 병합해서 배열 하나를 생성한다는 것을 보고 이해하여야 한다.
function removeItem(items, removable) {
if (items.includes(removable)) {
const index = items.indexOf(removable);
return [...items.slice(0, index), ...items.slice(index + 1)];
}
return items;
}
=> 펼침 연산자를 사용해서 하위 배열을 목록으로 하여 대괄호 안에 작성하고 배열을 반환한다는 것을 눈으로 알 수 있다.
const book = ['Reasons and Persons', 'Derek Parfit', 19.99];
function formatBook(title, author, price) {
return `${title} by ${author} $${price}`;
}
formatBook(book[0], book[1], book[2]);
formatBook(...book);
=> 함수의 인수 목록을 생성할 때 펼침 연산자를 사용하여 책에 대한 정보의 양이 바뀌었을 때도 고치지 않고 사용할 수 있다.
Tip 8. push() 대신 펼침 연산자로 원본 변경을 피하라.
const cart = [
{
name: 'The Foundation Triology',
price: 19.99,
discount: false,
},
{
name: 'Godel, Escher, Bach',
price: 15.99,
discount: false,
},
{
name: 'Red Mars',
price: 5.99,
discount: true,
},
];
const reward = {
name: 'Guide to Science Fiction',
discount: true,
price: 0,
};
function addFreeGift(cart) {
if (cart.length > 2) {
cart.push(reward);
return cart;
}
return cart;
}
function summarizeCart(cart) {
const discountable = cart.filter(item => item.discount);
if (discountable.length > 1) {
return {
error: '할인 상품은 하나만 주문할 수 있습니다.',
};
}
const cartWithReward = addFreeGift(cart);
return {
discounts: discountable.length,
items: cartWithReward.length,
cart: cartWithReward,
};
}
function summarizeCartUpdated(cart) {
const cartWithReward = addFreeGift(cart);
const discountable = cart.filter(item => item.discount);
if (discountable.length > 1) {
return {
error: '할인 상품은 하나만 주문할 수 있습니다.',
};
}
return {
discounts: discountable.length,
items: cartWithReward.length,
cart: cartWithReward,
};
}
function addGift(cart) {
if (cart.length > 2) {
return [...cart, reward];
}
return cart;
}
function summarizeCartSpread(cart) {
const cartWithReward = addGift(cart);
const discountable = cart.filter(item => item.discount);
if (discountable.length > 1) {
return {
error: '할인 상품은 하나만 주문할 수 있습니다.',
};
}
return {
discounts: discountable.length,
items: cartWithReward.length,
cart: cartWithReward,
};
}
function addWithPush() {
const titles = ['Moby Dick', 'White Teeth'];
const moreTitles = [...titles, 'The Conscious Mind'];
// ['Moby Dick', 'White Teeth', 'The Conscious Mind'];
}
function forgetting() {
// # START:forgetting
// 배열의 앞에 추가하기
const titles = ['Moby Dick', 'White Teeth'];
titles.shift('The Conscious Mind');
const moreTitles = ['Moby Dick', 'White Teeth'];
const evenMoreTitles = ['The Conscious Mind', ...moreTitles];
// 복사하기
const toCopy = ['Moby Dick', 'White Teeth'];
const copied = toCopy.slice();
const moreCopies = ['Moby Dick', 'White Teeth'];
const moreCopied = [...moreCopies];
=> addFreeGift()를 사용하면 배열 cart를 조작하게 되고 상품이 3개 이상이면 할인이 적용된 아이템이 추가된다. reward
=> addGift(): 기존 배열을 대괄호에 펼쳐 넣고, 새로운 상품을 배열의 마지막에 추가한다. 이렇게 되면 새로운 배열을 생성한다.
=> 대괄호 안에 배열과 펼침연산자 ...배열을 넣어 요소들을 넣을 수 있다.
=> slice(): 원본 배열을 건드리지 않고 새로운 배열로 복사하여 생성
Tip 9. 펼침 연산자로 정렬에 의한 혼란을 피하라.
[...staff].sort(sortByYears);
// [
// {
// name: 'Theo',
// years: 5
// },
// {
// name: 'Joe',
// years: 10
// },
// {
// name: 'Dyan',
// years: 10
// },
// ];
=> 배열을 정렬하기 전에 펼침 연산자로 새로운 배열을 생성한 뒤 sort()로 정렬한다. 이렇게 하면 원본 배열은 건드리지 않았으므로 같은 기준으로 정렬했을 때 항상 같은 결과를 확인할 수 있다.
=> 원본 배열을 정렬하는 식으로 사용하면 근속 연수에 따라 정렬하였다가 이름 순으로 정렬하였다가 다시 근속 연수로 정렬할 때 이름 순으로 정렬했던 흔적이 그대로 남게 되어 최초 근속 연수로 정렬했던 것과는 다른 결과가 나오게 된다. 데이터가 많은 실제 어플리케이션에서 이러한 현상이 일어나게되면 사용자는 정렬 결과가 바뀌는 결과를 신뢰할 수 없게 된다!
'JS' 카테고리의 다른 글
Next.js (3) | 2024.10.18 |
---|---|
3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라 (10~12) (3) | 2023.11.12 |
2장 배열로 데이터 컬렉션을 관리하라 (2) | 2023.10.28 |
1장 변수 할당으로 의도를 표현하라 (0) | 2023.10.21 |
1장 변수 할당으로 의도를 표현하라 (0) | 2023.10.08 |