본문 바로가기

개발/Javascript

[Javascript] const와 Object.freeze()를 이용하여 Immutable한 Object 만들기

 

프로그래밍을 하다보면 개발자의 실력과는 별개로 언제나 "Human Error"가 발생할 수 있다.

 

특히 개발자의 실수로 인해 의도치 않게 전역 공간이나 외부 스코프의 값이나 상태가 변경되는 “Human Error”는 언제든지 일어날 수 있으며, 추적이 어렵고, 프로그램에 치명적이다.

 

그래서 오늘은 Javascript에서 const와 Object.freeze를 사용하며 객체를 Immutable하게 만듦으로서 객체를 "Human Error'로 부터 보호하는 방법을 소개한다.

 

 

const

 

자바스크립트는 ES6(ECMA 2015)부터 let과 const 키워드를 제공한다.

 

이 중 const 키워드를 사용하면 상수 변수 선언을 할 수 있다. 그리고 const는 상수로 취급되기 때문에 다음과 같이 값을 변경하려고 시도하면 에러가 발생한다.

 

const hello = 'JS World';

hello = 'JS Hell'; // Uncaught TypeError: Assignment to constant variable.

 

하지만 자바스크립트의 const는 다른 여러 언어의 상수 취급과는 완전히 동일하지 않다.

 

그 이유는 정확히 얘기하면 ES6의 const는 할당된 값이 상수가 되는 것이 아니고, 바인딩된 값이 상수가 되기 때문이다.

 

이미 const를 사용해봤던 사람이라면 아래와 같이 const로 선언된 객체의 속성 변경 가능한 것을 알고 있을 것이다.

(모른다면 필자가 이전에 작성했던 "var, let, const의 차이점"을 먼저 읽고 오는 것을 추천한다.)

 

const b = {};
b.key = 'value';

console.log(b); // {'key': 'value'}

 

위 코드와 같이 const로 선언된 객체의 속성 변경이 가능한 이유는 실제 객체가 변경되는 것은 맞지만 const로 선언한 변수와 객체 사이의 바인딩은 변경되지 않기 때문이다.

 

따라서 가장 먼저 봤던 코드와 같이 변수 자체를 재할당하려는 경우에는 변수와 값 사이의 바인딩이 변경되어 오류가 발생하는 것이다.

 

프로그래밍에서 상수는 코드 내에서 개발자의 실수로 인해 값이 변경되지 않도록 변수를 보호하거나 다른 코드에서 실수로 이미 할당된 변수를 재할당하지 않도록 하는데 유용하기 때문에 많이 사용된다.

 

하지만 자바스크립트의 const로 객체를 선언할 경우에 객체의 속성은 언제든지 변경이 가능하기 때문에 immutable한 상수로 사용된다고 보기 어렵다.

 

그래서 const와 같이 유용하게 사용되는 것이 Object.freeze()이다.

 

 

Object.freeze()

 

자바스크립트에서 제공하는 Object.freeze()는 MDN 문서에서 "객체를 동결하기 위한 메서드"라고 설명하고 있다.

 

즉, Object.freeze를 사용하면 동결된 객체를 만들 수 있고, 동결된 객체에는 속성을 추가하거나 제거하는 동작이 불가능한 Immutable한 객체를 만들 수 있는 것이다. 

 

또한 Object.freeze로 동결된 객체는 프로토타입의 변경도 막아준다.

 

먼저 Object.freeze를 사용한 코드를 살펴보자.

 

let itGo = {
	elsa = 'Princess';
};

Object.freeze(itGo);

 

먼저 let으로 선언된 객체를 Object.freeze를 통해 동결된 객체로 만들었다.

 

따라서 아래와 같이 해당 객체의 속성을 변경하는 시도는 무시된다.

 

itGo.elsa = 'Prince';

console.log(itGo) // {elsa: "Princess"} -> Not Modified

 

하지만 Object.freeze는 동결된 객체를 반환할 뿐 재할당을 허용한다. 따라서 let으로 선언된 객체는 Object.freeze를 사용하더라도 다음과 같이 재할당 할 수 있다.

 

itGo = {
	'Olaf': 'Snowman'
};

console.log(itGo); // {'Olaf': 'Snowman'}

 

 

const + Object.freeze

 

위에서 살펴본 것과 같이 객체를 const로 선언할 경우 선언한 변수의 재할당은 허용하지 않지만 객체의 속성을 변경하는 것을 가능했다. 그리고 Object.freeze는 객체의 속성을 변경하는 것은 불가능하지만 재할당은 가능하다.

 

그렇다!

 

우리가 원하는 Immutable한 객체를 생성하기 위해서는 const와 Object.freeze를 함께 사용하면 된다.

 

아래 코드를 살펴보자.

 

const truth = {
	'dogIs': 'Cute'
};

Object.freeze(truth);

 

위 코드는 "강아지는 귀엽다" 라는 절대 불변의 진리(?)를 truth라는 객체의 속성으로 등록했다. 그리고 해당 truth 객체를 Object.freeze를 통해 동결된 객체로 만들었다.

 

그리고 해당 객체는 아래와 같이 재할당과 속성 변경이 불가능한 Immutable한 객체가 되었다.

 

truth.dogIs = 'Not Cute';

truth = {'catIs': 'Pretty'}; // Uncaught TypeError: Assignment to constant variable.

concole.log(truth); // {'dogIs': 'Cute'} // Not Modified

 


 

 

 

안녕하세요. 평범한 대학생 개발자 yorr입니다.

포스팅을 읽고 궁금한 점 또는 문의가 있으신 분은 메일 또는 댓글을 남겨주세요.

 

Mail: twysg@likelion.org

Github: https://github.com/sangyeol-kim

 

 

 

'개발 > Javascript' 카테고리의 다른 글

[Javascript] Async와 Promise  (0) 2019.11.22
[Javascript] var, let, const의 차이점  (0) 2019.06.17
[ES6] computed property name  (0) 2019.06.12