1차 공부/JavaScript

JavaScript 객체와 불변성이란?

공대탈출 2022. 11. 19. 16:41

글쓰기에 앞서 글쓴이는 코딩에 미숙한 사람임을 알립니다.

더 구글링 해보면 더욱 더 자세한 내용이 공식문서 혹은 블로그에 정리 되어 있을 수 있습니다.



기본형 데이터와 참조형 데이터

기본형 데이터 : 객체가 아닌 데이터 유형을 말한다. 원시형이라고도 한다.

                            기본형 데이터로는 숫자형, 문자형, 불린형, null, undefined가 있다.

 

참조형 데이터 :  기본형 데이터가아닌 모든 것을 의미한다.

                             참조형 데이터로는 객체, 함수, 배열, 클래스, ... 등 기본형 데이터가 아닌 모든 것이다.

 

불변 객체를 만드는 방법

일단 불변 객체란 무엇인가?

불변 객체(immutability)란 말 그대로 변하지 않는 객체, 즉 이미 할당된 객체가 변하지 않는 것이다.

 

기본적으로 const는 변수를 상수로 지정한다.

여기서 상수로 지정한다는 것은 const로 선언된 것은 값을 바꾸지 못한다는 것이다.

그러나 const로 선언된 객체의 경우 속성을 추가, 제거, 변경할 수 있어 불변객체라 하기엔 힘들다.

 

const test = {}
test.name = 'Jeon'
console.log(test)	//{name : 'Jeon'}
//위와같이 test라는 빈 객체에 키가 name이고 밸류가 Jeon인 속성을 추가하는 것이 가능하다.

따라서 let test = {age:15}와 같은 재할당은 const의 특성상 불가하지만 속성이 변경 가능하므로 불변속성이라 하긴 힘들다.

 

두번째로 Object.freeze() 메소드이다.

이는 객체를 동결하기위한 메소드인데 한번 살펴보자.

let test = {
	name: 'kim'
}
Object.freeze(test)	//동결 객체가 됨

test.name = 'Jeon'	// 속성 변경시도
console.log(test)	//{name : 'kim'} 속성이 변경되지 않음

test = {
	age: 15		//객체 재할당 시도
}

console.log(test)	//{age: 15} 객체 재할당이 성공함

위와같이 속성은 변경되지만, 객체test에 대한 재할당은 성공한다.

따라서 Object.freeze()도 단일로 불변객체를 만들수 있다고 하기에는 힘들어 보인다.

 

그러면 어떻게 불변객체를 만들 수 있을까?

바로 const와 Object.freeze()를 같이 사용하는 것이다.

const로 객체자체를 재할당 불가능하게 만들고, Object.freeze()로 객체 속성 변경을 불가하게 만든다.

const test = {		//const로 선언되어 객체 재할당이 불가하다.
	name : 'Jeon'
}
Object.freeze(test)	//Object.freeze()가 사용되어 객체 속성 변경이 불가하다.
//불변객체 만들기 성공!

 

얕은 복사와 깊은 복사

 

얕은 복사 : 얕은 복사는 원본 객체를 똑같이 복사하되, 객체의 주소값은 동일한 것이다.

                     주소값이 동일하기 때문에 복사객체를 변경하면 원본객체까지 동일하게 변경이 된다.

const 가 = [1,2]
const 나 = 가		//얕은 복사

나.push(3)
나.push(4)

console.log(가)	//[1,2,3,4]	나에 push되었음에도 주소값을 공유하기에 변경이 됨
console.log(나)	//[1,2,3,4]

 

깊은 복사 : 원본 객체와 동일하지만 주소는 다른 객체를 만드는 것이다.

                     주소값이 달라 복사개체의 변경에도 원본객체는 영향을 받지 않는다.

깊은 복사를 하는 방법에는 두가지가 있다.

 

먼저 ...을 사용하는 깊은 복사이다.

const 가 = [1,2]
const 나 = [...가]	//깊은 복사

나.push(3)
나.push(4)

console.log(가)		//[1,2]	나에 push되었지만 주소값이 달라 변경되지 않음
console.log(나)		//[1,2,3,4]

 

두번째로 Lodash의 cloneDeep을 사용하는 방법이다.

// Lodash라이브러리 설치 npm install lodash --save
// lodash불러오는 변수값 설정
const lodash = require('lodash')

let obj1 = {name:'Jeon', age:25}

let obj2 = lodash.cloneDeep(obj1)	//obj1을 깊은 복사함
obj2.name = 'kim'	//obj2의 name키 밸류 변경
console.log(obj1)	//{name:'Jeon',age:25} obj2의 변경에도 변하지 않음
console.log(obj2)	//{name:'kim',age:25} 변경 성공

 

끝.