어제의 나보다 성장한 오늘의 나

[자바스크립트] Object.freeze와 Deep Copy(assign) 본문

공부/JavaScript && jquery

[자바스크립트] Object.freeze와 Deep Copy(assign)

NineOne 2021. 4. 26. 20:36

object.freeze()

자바스크립트에서 const의 특성을 알고 있을 것이다. const는 한번 선언된 변수의 값을 변경할 수 없는데, const가 객체를 참조하고 있다면 객체 안에 프로퍼티들의 값은 변경을 할 수 있는 이슈가 있다. 그렇다면 객체 안에 프로피터들의 값들도 변경을 할 수 없게 만드는 방법이 무엇이 있을까? 그것은 바로 object.freeze()로 해결할 수 있다.

const OBJ = {
  prop1 : 1,
  prop2 : [2, 3, 4],
  prop3 : { a: 1, b: 2 }
}
Object.freeze(OBJ)
OBJ.prop1 = 3
OBJ.prop2.push(5)
OBJ.prop3.b = 3
console.log(OBJ)

다음과 같이 OBJ 객체를 선언해보자 Object.freeze(OBJ)를 하고 값들을 변경해보자 그러면 어떻게 결과값이 나올까? 다음과 같이 나온다.

prop1은 객체를 참조하고 있지 않는 상수 임으로 변경이 안되었다. 하지만 prop2와 prop3 같은 경우는 객체를 참조하고 있기 때문에 freeze()에 해당이 안 되는 것이다. 그렇다면 prop2와 prop3는 어떻게 할까? 답은 프로퍼티가 객체를 참조하고 있다면 계속 freeze()를 해주는 것이다.

그럼 이제 위에 코드에서 아래 코드를 추가해보자

Object.freeze(OBJ.prop2)
OBJ.prop2.push(6)
console.log(OBJ)

Object.freeze(OBJ.prop2)를 하고 값을 바꾸게 되면 결괏값을 바꿀 수 없다고

다음과 같이 에러가 뜨게 된다.

 

Deep Copy(assign)

Java나 C++을 해본 사람이라면 얇은 복사와 깊은 복사를 들어 봤을 것이다. 그렇다면 자바스크립에서는 어떻게 사용할까?

var a = {
  a : 1,
  b : [1,2,3],
  c : {d: 1, e:2}
}

var b = Object.assign({}, a);
b.b[1] = 20;
console.log(a.b); // 결과값 [1, 20, 3]

다음과 같이 object.assign 함수로 복사를 할 수 있다. 하지만 b.b [1]= 20으로 값을 바꿔보니 a.b도 변경이 되어 있다. 그것은 위에서 설명한 object.freeze와 똑같다. b는 a의 주소 값을 복사한 것이기 때문에 a 안에 있는 객체 프로피터의 주소를 복사한 것이기 때문에 얇은 복사가 되는 것이다.

var a = {
  a : 1,
  b : [1,2,3],
  c : {d: 1, e:2}
}

var b = Object.assign({}, a);
b.b = Object.assign([], a.b);

b.b[1] = 20;
console.log(b); // b : 결과값 [1, 20, 3]
console.log(a); // b : 결과값 [1,2,3]

다시 a.b에 있는 값을 b.b에 복사하면 b 프로퍼티에 대한 깊은 복사가 되는 것이다. 하지만 c에 대한 복사는 하지 않았다. 

따라서 이런 깊은 복사를 해야만 immutable 하다! 불변 객체라고 하고 이렇게 해야만 매번 다른 객체를 복사할 때마다 동 떨어진 객체가 만들어진다.

 

출처

Comments