프로젝트를 진행하던 중에 객체의 형식을 상수로 만들어서 초기값을 모조리 0으로 두고, 이걸 state의 초기값으로 담았었다.
이 변수의 값을 api 작업을 통해 바꿔주게 되었었고, 이 값을 setState를 통해 바로 state를 변경시켜주었다.
그런데 여기서 예상치 못한 일이 생겼다. setState로 변경을 했는데 값이 2번 변경되어 count가 +1이 되어야 하는데 +2가 돼버린 것이다..
이는 상수로 만든 객체를 참조하고 그대로 변형시켜 버린 탓이었다.
객체 참조가 이루어지기 때문에, 설령 state의 값을 변경하더라도 원래 상수의 초기값인 0도 같이 늘어나 +1이 됐던 것이다.
따라서 state의 count+1, 상수 객체의 count+1가 되어 도합 count+2가 된 것이다.
이 경험으로 인해서 객체의 불변성에 대한 이해가 중요하다는 것을 깨닫고 공부를 하게 되었다.
JavaScript 객체의 불변성
객체의 불변성(immutability)은 한 번 생성된 객체가 변경되지 않음을 의미한다.
즉 객체의 내용이나 상태가 변경되지 않는 것을 뜻하며, 불변성은 프로그래밍에서 중요한 개념이다.
객체의 불변성이 중요한 이유 ?
1. 예측 가능한 코드
- 불변한 객체는 변경되지 않기 때문에 코드의 동작을 예측하기 쉽다. 객체의 상태가 변경되지 않으면 같은 입력이 주어졌을 때 항상 같은 결과가 나오게 된다.
2. 쓰레드 안정성
- 멀티 쓰레드 환경에서는 동일한 객체에 여러 쓰레드가 동시에 접근할 수 있다. 이 때, 객체가 변경되면 예기치 않은 결과가 발생할 수 있는데, 불변한 객체는 변경되지 않기 때문에 쓰레드 간의 충돌없이 안정하게 공유될 수 있다.
3. 변경 추적의 용이성
- 객체의 불변성은 변경 내역을 추적하기 쉽게 만든다. 변경된 객체의 본사본을 만들거나 변경 이전의 객체를 유지하는 등의 방법으로 변경 내역을 추적할 수 있다.
4. 성능 향상
- 불변한 객체는 변경할 필요가 없기 때문에 메로리 사용량을 줄일 수 있다. 또한, 객체의 해시값 등을 미리 계산해두어 캐싱할 수 있어 성능이 향상 될 수 있다.
const obj1 = { name: "ho-pak" };
const obj2 = obj1;
obj2.name = "sang-ho";
console.log(obj1, obj2);
// { name: 'sang-ho' } { name: 'sang-ho' }
위와 같이 객체를 복사 할 경우 단순하게 값을 복사하는 것이 아닌 참조를 하게된다.
원시 타입, 객체 타입 모두 참조를 하게 되는데, 원시 타입의 경우는 값 자체가 저장되는 반면에, 객체의 경우는 원본 객체의 고유한 주소가 할당이 된다.
주소가 할당이 되기 때문에, 값을 복사하더라도 원본 객체의 값에 접근하고 수정할 수 있게 된다.
따라서 값만을 복사하고자 새로운 변수에 할당하더라도, 복사한 객체의 key값을 변경할 경우 원본 객체까지 변경되는 상황이 발생한다.
이에 따라 원본 객체를 변형시키지 않기 위해서는 객체의 불변성을 유지할 필요가 있다.
객체의 불변성을 유지하는 방법은 ?
1. 새로운 객체 생성
- 객체를 변경하는 대신에 새로운 객체를 생성하여 원본 객체의 불변성을 유지한다. 객체를 복제하고, 수정된 사본을 반환하는 함수를 사용해 새로운 객체를 생성할 수 있다.
function updateObject(oldObject, newProperties) {
return { ...oldObject, ...newProperties };
}
const originalObject = { a: 1, b: 2 };
const updatedObject = updateObject(originalObject, { b: 3 });
console.log(originalObject, updatedObject);
// { a: 1, b: 2 } { a: 1, b: 3 }
2. 객체의 프로퍼티 변경 방지
- 'Object.freeze()' 메서드를 사용해 객체의 프로퍼티 변경을 막을 수 있다. 이 메서드를 사용하면 객체의 프로퍼티를 읽기 전용으로 만들어 변경할 수 없게 된다.
const immutableObject = Object.freeze({ a: 1, b: 2 });
immutableObject.c = 3; // TypeError: Cannot add property 'c', object is not extensible
3. 객체의 프로퍼티 새로운 값 할당
- 객체의 프로퍼티를 변경할 때마다 새로운 객체를 생성하여 할당한다. 이를 통해 기존 객체의 상태를 변경하지 안혹 새로운 객체를 생성하여 분변성을 유지할 수 있다.
const originalObject = { a: 1, b: 2 };
const updatedObject = { ...originalObject, b: 3 };
console.log(originalObject, updatedObject);
//{ a: 1, b: 2 } { a: 1, b: 3 }
4. 불변성 라이브러리 사용
- Immutable.js와 같은 라이브러리를 사용해 불변성을 유지할 수 있다. 이러한 라이브러리는 불변성을 지원하는 다양한 메서드와 자료구조를 제공해 개발자가 쉽게 불변성을 유지할 수 있도록 돕는다.
const { Map } = require("immutable");
const originalMap = Map({ a: 1, b: 2 });
const updatedMap = originalMap.set("b", 3);
'JavaScript' 카테고리의 다른 글
비동기 (0) | 2022.09.16 |
---|---|
2022.03.07 (0) | 2022.03.08 |
object 객체 (Javascript, 코린이 공부) (0) | 2022.02.24 |
배열이란.. (Javascript, 코린이 공부) (0) | 2022.02.24 |
const와 let의 차이 그리고 string (Javascript, 코린이 공부) (0) | 2022.02.24 |