hoon's bLog

Javascript 자바스크립트 코딩의 기술 3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라 (1) 본문

IT/Javascript

Javascript 자바스크립트 코딩의 기술 3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라 (1)

개발한기발자 2024. 1. 4. 09:30
반응형


3장 특수한 컬렉션을 이용해 코드 명료성을 극대화하라

tip10. 객체를 이용해 정적인 키-값을 탐색해라

  • 원칙적으로 객체는 변화가 없고 구조화된 키-값 데이터를 다루는 경우에 유용하다.
  • "."을 통해 직접 참조하거나 배열처럼 접근이 가능하다.
  • 이처럼 객체는 단순하여 정적인 정보를 다룰 때 훌륭하다.
  • 하지만 계속해서 갱신, 반복, 대체, 정렬해야 하는 정보에는 그닥 비추!..
  • 단, 기존의 객체를 조작하는 것이 아니라 각각의 함수에서 새로운 객체를 생성하면 조작없이 사용 가능하다.
const colors = {
    red: '#d10202',
    green: '#19d836',
    blue: '#0e33d8'
}
  • 위와 같이, 데이터가 변경될 가능성이 없는 색상 컬렉션을 공유하는 경우에는 객체를 선택하는 것이 좋다.
  • 중괄호에 key-value를 작성하는 것을 객체 리터럴object literal이라고 한다.
function getBill(item) {
    return {
        name: item.name,
        due: twoWeeksFromNow(),
        total: calculateTotal(item.price),
    };
}

const bill = getBill({
    name: '객실 청소',
    price: 30
});

function displayBill(bill) {
    return `${bill.name} 비용은 ${bill.total} 달러이며 납부일은 ${bill.due}입니다.`;
}
  • 위 코드에서는 함수 내에서 각각 함수에서 (새로운)객체를 생성하고 다른 함수에 넘겨준다.
  • 이렇게 하면 조작 또는 갱신을 하지 않으므로 정적인 정보가 된다. 

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

ES6에서는 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;
}

addBookDefaults(book, defaults);
// Results: {author: "Joe Morgan", title: "Simplifying Javascript", year: 2017, rating: null}

위 코드는 객체 book, defaults를 함수 addBookDefaults로 넘겨, 새로 선언한 빈 객체 updated에 해당 객체를 출력하고 있다.

잘 작동하고 있지만 코드 간결화를 위해 Object.assign()을 이용하면 아래 코드와 같다.

const defaults = {
    author: '',
    title: '',
    year: 2017,
    rating: null
}
const book = {
    author: 'Joe Morgan',
    title: 'Simplifying JavaScript'
}

// 먼저 전달한 객체부터 적용됨
Object.assign(defaults, book);
// Results: {author: "Joe Morgan", title: "Simplifying Javascript", year: 2017, rating: null}
  • 언뜻 보면 잘 작동해 보이는 듯 하나, 13 line의 Object.assign(defaults, book) 이후 defaults 객체를 확인해보면 book 객체의 정보로 수정된 걸 볼 수 있다.
  • Object.assign을 사용하면 코드는 간결해지지만, 원본 객체를 조작하게 되므로 아래 코드와 같이 첫 번째 객체에 빈 객체를 사용한다.
Object.assign({}, defaults, book);
// Results: {author: 'Joe Morgan', title: 'Simplifying Javascript', year: 2017, rating: null}
  • 이렇게 사용하면 다시 defaults를 확인해도 원본 값은 변하지 않음을 확인 할 수 있다.

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

책에서는 펼침 연산자라고 지칭하지만 스프레드 연산자로 정리하겠다.(너무 번역투....)

스프레드 연산자는 마침표 세 개...로 표시하며 자바스크립트에서 아주 중요한 연산자이다.
배열뿐만 아니라 Map Collection이나 Generator를 이용하는 데이터 구조 등에서도 사용할 수 있다.

const book = {
    title : 'Reasons and Persons',
    author: 'Derek Parfit'
}
const update = { ...book, title: 'Reasons & Persons' }
  • 새로운 데이터를 스프레드 연산자 앞, 뒤에 쉽게 추가할 수 있다.
  • 또한 독립적으로 사용할 수는 없고 객체에 펼쳐지게 해야 한다.
  • 동일한 키에 서로 다른 값을 추가하면 어떤 값이든 가장 마지막에 선언된 값을 사용한다는 것!!

tip13. Map으로 명확하게 키-값 데이터를 갱신하라

객체보다 Map을 더 선호하는 경우는 다음과 같다.

  • key-value 쌍이 자주 추가되거나 삭제되는 경우
  • 키가 문자열이 아닌 경우

예제를 통해 알아보자.

const dogs =[
  {
    이름: '맥스',
    크기: '소형견',
    견종: '보스턴테리어',
    색상: '검정색'
  },
  {
    이름: '도니',
    크기: '대형건',
    견종: '래브라도레트리버',
    색상: '검정색'
  },
  {
    이름: '섀도',
    크기: '중형견',
    견종: '래브라도레트리버',
    색상: '갈색'
  }
]

function addFilters(filters, key ,value) {
    filters[key] = value; // 객체 자체 메서드 사용
}
function deleteFilters(filters, key) {
    delete filters[key]; // 언어에 정의된 delete연산자 사용
}
function clearFilters(filters) {
    filters = {}; // 변수 재할당
    return filters;
}
  • 위와 같은 객체에 추가, 삭제 등 자주 변경되는 경우에는 인터페이스가 명확하고, 메서드가 예측 가능하고, 반복과 같은 동작이 내장되어 있는 Map을 사용하는 게 좋다.
  • 아래 코드는 Map의 set/get을 이용해 객체를 생성하고 값을 가져오는 방법이다.
// chainning(메서드를 차례대로 연결)을 이용한 key-value 설정
let filters = new Map(); // Map 객체 선언
filters.set('견종', '래브라도레트리버'); // 키, 값 set
filters.get('견종'); // '견종' 키로 값, Results: 래브라도레트리버

let filters = new Map().set('견종', '레브라도레트리버')
    .set('크기', '대형견')
    .set('색상', '갈색');

filters.get('크기'); // Results: 대형견
  • 다음은 위에 addFilters, deleteFilters, clearFilters를 Map을 이용해 다시 리팩토링 하면,
function addFilters(filters, key, value) {
    filters.set(key, value);
}

function deleteFilters(filters, key) {
    filters.delete(key);
}

function clearFilters(filters) {
    filters.clear();
}
  • delete() 메서드를 사용하기 때문에 인스턴스를 생성한 후에는 언어 수준의 연산자를 섞지 않는다.
  • clear() 메서드를 사용하기 때문에 인스턴스를 생성할 필요 없다.
  • 따라서 변경 사항이 많을때는 객체보다 맵이 좋다.
const errors = {
    100: '이름이 잘못되었습니다.',
    110: '이름에는 문자만 입력할 수 있습니다.',
    200: '색상이 잘못되었습니다.'
};
Object.keys(errors); 
// ['100','110','200']

const errorsMap = new Map([
    [100, '이름이 잘못되었습니다.']
    [110, '이름에는 문자만 입력할 수 있습니다.']
    [200, '색상이 잘못되었습니다.']
]);
errors.keys();
// MapIterator { 100, 110, 200 }
  • 키에 사용할 수 있는 자료형에 제약이 없음, 정수를 객체의 키 값으로 사용한다면 문자열로 변경됨

Reference

자바스크립트 코딩의 기술 요약 / 정리

728x90
반응형