자바스크립트 코딩의 기술_Collection으로 데이터 관리하기_1

자바스크립트 2021. 5. 23. 16:19

(본 포스팅은 길벗의 '자바스크립트-코딩의 기술' 책을 공부하면서 작성되었습니다_내돈내산)

 

1. 객체(Object)를 이용해 정적인 키-값(key-value)를 탐색하라.

  • 원칙적으로 객체는 변화가 없고 구조화된 키-값 데이터를 다루는 경우에 유용하다. 반면 자주 갱신되거나 실행되기 전에는 알 수 없는 동적인 정보를 다루기엔 적합하지 않다.(정적인 정보에 적합하다)
  • 계속해서 갱신, 반복, 대체, 정렬해야 할 정보에는 맵을 사용하는 것이 낫다.
  • 정보의 경로를 알고 있을 때 적절한 방법이다.
  • 함수 내에서 객체를 생성하고 이를 다른 함수에 넘겨줄 수 있다. 이런식으로 할 경우 정보를 조작하거나 갱신하지 않기 때문에 정적인 정보가 된다.
//  # START:book
const book = {
  title: 'ES6 Tips',
  author: 'Joe Morgan',
  date: 2017,
};
//  # END:book

//  # START:config
export const config = {
  endpoint: 'http://pragprog.com',
  key: 'secretkey',
};
//  # END:config

//  # START:between
function getBill(item) {
  return {
    name: item.name,
    due: twoWeeksFromNow(),
    total: calculateTotal(item.price),
  };
}

const bill = getBill({ name: 'Room Cleaning', price: 30 });

function displayBill(bill) {
  return `Your total ${bill.total} for ${bill.name} is due on ${bill.due}`;
}
//  # END:between
  • 위의 예제에 대해 간단히 설명해보자면, 객체간에 이동시키는 정보에 구조를 추가하기 위해 객체를 사용하였다.
  • 함수 displayBill( )은 각 항목을 매개변수로 받는 대신, 객체를 전달해 필요한 값을 꺼내 쓸 수 있도록 했다.
  • 이런식으로 사용하게 될 경우 객체는 다른 컬렉션에 비해 빠르고 명료할뿐아니라 object destructuring도 가능해서 객체로 데이터를 다루는것이 매우 빠르고 간결해진다.

2. Object.assign( )으로 조작없이 객체를 생성하라.

  • 앞서 배열에서도 살펴봤듯이 객체에서도 조작과 부수효과로 인한 문제에 직면할 가능성이 존재한다.
  • 객체에 무심코 필드를 추가하거나 설정하면 예상할 수 없는 문제가 발생할 가능성이 생긴다.
  • 부수효과나 조작없이 기본값을 설정하며, 원래의 데이터를 유지하는 새로운 객체를 생성하는 코드를 구현해보자
const defaults = {
  author: '',
  title: '',
  year: 2017,
  rating: null,
};

const book = {
  author: 'Joe Morgan',
  title: 'Simplifying JavaScript',
};

function addBookDefaults(book, defaults) {
  const fields = Object.keys(defaults);
  const updated = {};
  for (let i = 0; i < fields.length; i++) {
    const field = fields[i];
    updated[field] = book[field] || defaults[field];
  }
  return updated;
}
  • 위의코드에 대해 문법적이거나 조작, 부수효과 등 오류는 없지만 매우 장황하고 반복문을 사용해 가독성이 떨어지는 단점이 존재한다. 이때 Object.assign( )을 이용하면 다른 객체의 속성을 이용해 객체를 갱신할 수 있음.
  • Object.assign( )은 일련의 객체를 전달받고 가장 먼저 인수로 받은 객체를 뒤이어 인수로 넘긴 객체의 키-값을 이용해 갱신한다. 그리고 나서 갱신된 첫 번째 객체를 반환한다. 호출시 인수 순서대로 적용되므로, 먼저 전달한 객체부터 적용되고 가장 나중에 전달한 객체가 맨 마지막으로 적용된다.

 

const book = {
  author: 'Joe Morgan',
  title: 'Simplifying JavaScript',
};

const defaults = {
  author: '',
  title: '',
  year: 2017,
  rating: null,
};

//  # START:mutate
Object.assign(defaults, book);

// {
//   author: 'Joe Morgan',
//   title: 'Simplifying JavaScript',
//   year: 2017,
//   rating: null,
// }
//  # END:mutate

//  # START:mutate2
const anotherBook = {
  title: 'Another book',
  year: 2016,
};

Object.assign(defaults, anotherBook);

// {
//   author: 'Joe Morgan',
//   title: 'Another book',
//   year: 2016,
//   rating: null,
// }
//  # END:mutate2
  • 위의 코드를 보면 대략 작동방식을 추측가능할것이다. 기존 디폴트 객체에 있던 키값과 같은 키의 value값을 대입시킨다. 하지만 원본객체가 변경되어 default의 값이 변해버리는 문제가 발생하였다.
  • 이러한 문제를 피하기 위해 첫번째 들어가는 객체에 빈 객체를 사용하는 것이 가장 좋다. 그렇게 하면 빈 객체에 새로운 값이 갱신되어 반환되어 다른 객체에는 조작이 발생하지 않게 된다.
// # START:deep
const defaultEmployee = {
  name: {
    first: '',
    last: '',
  },
  years: 0,
};

const employee = Object.assign({}, defaultEmployee);
// # END:deep
  • 하지만 Object.assign( )을 이용하는 경우 값만 복사된다. value값이 다른 객체인 경우 깊은복사(deep copy)가 발생하지 않게 된다. 이런경우에는 중첩된 객체까지 전부 Object.assign( )을 통해 복사해주도록 하면 된다.
// # START:deepMutate
employee.name.first = 'Joe';

defaultEmployee;

// {
//   name: {
//     first:'Joe',
//     last: '',
//   },
//   years: 0
// }
// # END:deepMutate


// # START:deepMerge
const employee2 = Object.assign(
  {},
  defaultEmployee,
  {
    name: Object.assign({}, defaultEmployee.name), // 중첩객체의 깊은복사가 이루어짐.
  },
);
// # END:endMerge

3. 객체 펼침 연산자로 정보를 갱신하라.

  • Object.assign( )의 이점을 객체 펼침 연산자의 간단한 문법으로 대체가 가능하다.
  • 객체펼침연산자의 경우 키-값 쌍을 목록에 있는 것처럼 반환한다. 새로운 정보는 펼침연산자의 앞이나 뒤에 쉽게 추가할 수 있으며, 또한 배열 펼침연산자와 마찬가지로 독립적으로 사용할 수는 없고 객체에 펼쳐지게 해야한다.
  • 배열 펼침 연산와 다른 점은 동일한 키에 서로 다른 값을 추가하면 어떤 값이든 가장 마지막에 선언된 값을 사용한다는 것이다.
  const book = {
    title: 'Reasons and Persons',
    author: 'Derek Parfit',
  };

  const update = { ...book, title: 'Reasons & Persons' };

  // { title: 'Reasons & Persons', author: 'Derek Parfit' }
  • 앞에서 배웠던 Object.assign( )을 이용한 방법과 객체펼침연산자를 이용한 방법의 차이점을 보면
// Object.assign() 사용
const employee2 = Object.assign(
  {},
  defaultEmployee,
  {
    name: Object.assign({}, defaultEmployee.name),
  },
);

// 객체 펼침 연산자 사용
 const employee = {
    ...defaultEmployee,
    name: {
      ...defaultEmployee.name,
    },
  };
  • 위와같이 사용이 가능하며, 항상 빈객체로 시작해야한다는 점을 기억할 필요도 없기 때문에 조작에 대한 우려도 줄일 수 있다.

 

admin