📜 Js

[JavaScript] 변수에 대한 불변성 정리(const, defineProperty)

loose 2022. 12. 18. 12:32
반응형

Const

 

변수를 불변하게 만들기 위해서 대표적으로 사용되는 것은 const(상수)다.

const name = 'loose';
console.log(name); // loose

하지만 const에 아래와 같이 객체 형태의 값을 넣으면 객체 내부의 속성은 변경이 가능해진다.

const x = {};

x.foo = 'bar';
console.log(x); // {foo : 'bar'}

x.foo = 'bar2';
console.log(x); // {foo : 'bar2'}

x = {}; // 불가능

위와같이 x에 foo라는 속성을 추가하거나 수정하는 것은 가능하다.

하지만 x를 재정의 하는 것은 불가능하다.

 

이것은 자바에서 Final과 같다.

자바에서도 Final을 쓰면 변수를 상수로 만들 수 있지만 Final로 설정된 객체의 내부 속성에 대한 변경까지는 막을 수 없다.

그래서 Constant(상수)는 Read-Only가 아니다라는 점을 알고가야한다.

Constant는 재할당(Reallocation)이 불가능하다라는 측면에서 사용된다.

많은 사람들이 상수를 Read-Only라고 생각하는 오류를 범한다. 

다시 말해서 상수는 Read-Only가 아니다.

그럼 내가 원하는 Read-Only를 적용하고 싶다면 어떻게 할까?

 

Object.freeze()

Object.freeze()를 쓰면 객체 속성에도 Read-Only가 적용된다.

정수형이나 문자형 뿐만 아니라 객체형도 전부 Read-Only를 적용시킬 수 있다.

const x = Object.freeze(['a'])
x.push('b')

Object.seal()

Object.seal()은 객체 속성에 대한 수정은 가능하지만 속성을 확장하는 것은 불가능하다.

var obj = {
	value: 10
};

Object.seal(obj);
obj.value = 20;
console.log(obj.value);

obj.name = "loose"; // 새로 넣는건 불가능
console.log(obj.name)

Object.defineProperty()

const obj = {};

Object.defineProperty(obj, 'a', {
  value: 100,
  writable: false
});

obj.a = 200;
obj.a === 100; // true

위에서 배운 freeze()나 seal()은 전부 defineProperty()라는 메소드를 통해 정의된 메소드라고 봐도된다.

writable을 false로 줘서 freeze()와 같은 설정이 가능하다.

각각의 객체마다 속성을 알고 싶다면 아래의 코드를 사용해서 확인할 수 있다.

Object.getOwnPropertyDescriptors(obj);

 

728x90