불변객체(Immutable Object)는 최근 React, Vue.Jjs, Angular 등의 라이브러리나 프레임워크뿐만 아닌 함수형 프로그래밍 과 디자인 패턴 등에서 매우 중요한 기초 개념이다.
기본개념:
새로운 데이터를 할당하고자 하면, 기본형 데이터와 마찬가지로 기존 데이터는 변하지 않는다.
어떤 상황에서 사용할 수 있을까?
값으로 전달받은 객체에 변경을 가하더라도 원본 객체는 변하지 않아야 하는 경우
const user = {
name: "Kim",
gender: "male"
}
const changeName = (user, newName) => {
return{
name: newName,
gender: user.gender
}
}
const user2 = changeName(user, "Jung")
if(user !== user2){
console.log("변경 되었습니다")
}
변경 전과 변경 후에 서로 다른 객체를 바라볼 수 있도록 한다.
그러나 만약 데이터가 많아 진다면 위의 방식은 사용하기 매우 힘들어 진다.
이에 대한 해결책으로 대상 객체의 프로퍼티 갯수에 상관 없이 모든 프로퍼티를 복사하는 함수를 만든다면, 편리해 질 것이다.
- 깊은복사
const user = { name: "kim", urls: { blog: "http://blog.com", facebook: 'http://facebook.com/kim' } } const copyObjectDeep = (target) => { let result = {}; if(typeof target === 'object' && target !== null){ for(let prop in target){ result[prop] = copyObjectDeep(target[prop]); } }else{ result = target; } return target } copyObjectDeep(user)
target 이 객체인 경우 내부 프로퍼티들을 순회하며, copyObjectDeep 함수를 재귀적으로 호출한다.
객체가 아닌 경우, 그대로 target을 리턴한다.
객체의 원본과 사본이 서로 완전히 다른 객체를 참조하게 되므로, 어떤 프로퍼티를 변경해도 다른 쪽에 영향을 주지 않는다.
- JSON을 활용한 깊은 복사
const user = { name: "kim", urls: { blog: "http://blog.com", facebook: 'http://facebook.com/kim' } } const copyObjectJSON = (target) => { return JSON.parse(JSON.stringify(target)); } copyObjectJSON(user)
객체를 JSON문법으로 표현된 문자열로 전환했다가 다시 JSON 객체로 바꾸는 원리
그러나 JSON으로 변경할 수 없는 프로터티들은 모두 무시한다.
httpRequest로 받은 데이터를 저장한 객체를 복사할 때 등 순수한 정보를 다룰 때 활용하기 좋은 방법이다.