티스토리 뷰

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()로 정렬한다. 이렇게 하면 원본 배열은 건드리지 않았으므로 같은 기준으로 정렬했을 때 항상 같은 결과를 확인할 수 있다.

 

=> 원본 배열을 정렬하는 식으로 사용하면 근속 연수에 따라 정렬하였다가 이름 순으로 정렬하였다가 다시 근속 연수로 정렬할 때 이름 순으로 정렬했던 흔적이 그대로 남게 되어 최초 근속 연수로 정렬했던 것과는 다른 결과가 나오게 된다. 데이터가 많은 실제 어플리케이션에서 이러한 현상이 일어나게되면 사용자는 정렬 결과가 바뀌는 결과를 신뢰할 수 없게 된다!

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함