-
Object.assign, spread operator, deep mergingDEV/Javascript 2022. 2. 7. 18:01
리액트 컴포넌트 설정을 유저가 변경할 수 있게 만들려면, 우선 기본 설정 값을 객체로 제공하고 프로퍼티로 커스텀 설정 값을 받아들여 두 객체를 합쳐야 한다. 조건은 1) 커스텀 설정 값이 무조건 우선으로 오게 하고, 2) 그 값이 없는 경우에는 기본 설정 값을 사용한다.
간단한 객체 구조인 경우, 즉 깊이가 1인 객체인 경우 그냥 spread 연산자나 Object.assign()으로 간단하게 해결이 가능하다. spread 연산자와 Object.assign의 차이점은 MDN에 나와 있듯이, Object.assign은 setter 함수를 트리거하는 반면 spread 연산자는 그렇지 않다는 점이다. Setter 함수는 속성 값 설정이 일어날 때마다 호출할 함수를 속성에 묶는다(bind). 둘 사이의 간단한 성능 차이 비교 결과는 여기서 확인하면 된다. 하지만 실제 업무에서 얼마나 영향이 있는지는 경험한 바 없다. (하지만 setter 함수 트리거가 굳이 필요 없다면 spread 연산자를 사용하는 편이 낫지 않으려나? 그런데 이 부분은 더 조사가 필요하다. setter 함수 트리거가 된다면 어떤 효과가 있는 것인지? 그렇다면 다음에 속성 값을 얻어올 때 getter 함수가 호출되나? 그렇지만, static value를 받아오는 경우라면 spread operator를 사용하는 편이 컴퓨터 입장에서도 그렇고 사용자 입장에서도 그렇고 단계가 더 간단하리라 예측해본다.)
깊이가 2 이상 넘어가면 deep merging을 해야 한다. 모든 프로퍼티를 순회하여 커스텀 설정값과 기본 설정값을 합치면 되겠지만, 이미 잘 만들어진 라이브러리를 의존성으로 가져다 쓰는 편이 정신 건강에 이롭기 때문에 찾아봤다. lodash.merge 혹은 deepmerge 정도가 괜찮은 것 같다. 주의할 점은 lodash.merge를 쓸 때 첫 번째 인자로 빈 객체를 넘겨야 한다는 점이다. deepmerge의 경우는 빈 객체를 넘기지 않아도 매번 객체를 새로 만들어주는데, lodash.merge는 Object.assign처럼 작동하기 때문에 빈 객체를 넘기지 않는 경우, 다른 곳에서 동일한 형태의 객체를 넘기면 두 객체가 꼬이는 오류가 있었다. (실수로 인해 발견한 사실!)
lodash.merge와 lodash.assign의 차이점은 아래 블로그에 잘 정리돼있다.