
ES6에서는 const 키워드를 사용하여 불변 변수(Immutable Variable)를 선언할 수 있다.
하지만 여기서 중요한 점은
"불변 변수는 값을 다시 할당할 수 없지만, 내부 값을 변경할 수는 있다"는 것이다.
이 말이 조금 헷갈릴 수 있는데, 하나씩 알아보자.
책에서는 불변 변수는 값을 직접 수정할 수 없지만, 객체나 배열의 내장 함수를 사용하면 내부 값을 변경할 수 있다고 설명하고 있다.
그러나 이런 방식은 무결성 제약 조건(Invariant Constraint)에 위배된다고 한다.
📌 무결성 제약 조건이란?
const person = { name: "Alice", age: 25 };
// 원본 데이터를 직접 수정하면 무결성 제약 조건에 위배됨
person.age = 30;
console.log(person); // { name: "Alice", age: 30 }
🚨 여기서 문제점
const로 선언했지만, 객체 내부의 속성은 여전히 변경할 수 있다.const person = { name: "Alice", age: 25 };
// 기존 객체를 유지하면서 새로운 객체 생성
const updatedPerson = { ...person, age: 30 };
console.log(person); // { name: "Alice", age: 25 } (원본 유지)
console.log(updatedPerson); // { name: "Alice", age: 30 } (새로운 객체)
📌 이렇게 하면 원본 데이터를 변경하지 않고 새로운 객체를 생성하여 적용할 수 있다!
📌 이 방식이 바로 불변성을 유지하면서 값을 변경하는 올바른 방법이다.
✅ 1) 상태 변화 추적이 쉬워진다.
✅ 2) 예측 가능성이 높아지고 버그를 방지할 수 있다.
✅ 3) React에서 상태 관리를 위해 필수적이다.
useState, useReducer를 사용할 때, 불변성을 유지해야 상태 변경을 감지하고 리렌더링을 정상적으로 수행할 수 있다.📌 기존 데이터를 직접 수정하지 않고, 새로운 데이터를 생성하는 방식을 사용해야 한다.
📌 이를 위해 가변 내장 함수(Mutable Methods) 대신 무결성 내장 함수(Immutable Methods)를 사용해야 한다.
| 가변 내장 함수 (원본 변경 🚨) | 무결성 내장 함수 (새로운 값 반환 ✅) |
|---|---|
push(...items) (값 추가) | concat(...items) |
splice(s, c, ...items) (특정 위치 변경) | slice(0, s).concat(...items, slice(s+c)) |
pop() (마지막 요소 제거) | slice(0, len - 1) |
shift() (첫 번째 요소 제거) | slice(1) |
const arr = [1, 2, 3];
arr.push(4); // 🚨 원본 배열이 변경됨
console.log(arr); // [1, 2, 3, 4]
arr.pop(); // 🚨 원본 배열이 변경됨
console.log(arr); // [1, 2, 3]
❌ push(), pop() 같은 가변 내장 함수는 원본 배열을 직접 수정하므로 불변성을 깨뜨린다.
❌ 이런 방식은 React 같은 라이브러리에서 상태 관리할 때 문제가 될 수 있다.
const arr = [1, 2, 3];
// ❌ 가변 함수 대신 ✅ 무결성 함수 사용!
const newArr = arr.concat(4); // 새로운 배열 반환
console.log(arr); // [1, 2, 3] (원본 유지)
console.log(newArr); // [1, 2, 3, 4] (새로운 배열)
✅ concat(), slice() 같은 무결성 내장 함수를 사용하면 원본을 변경하지 않고 새로운 배열을 반환할 수 있다!
✅ 이런 방식이 불변성을 유지하면서 데이터를 다루는 올바른 방법이다.
배열뿐만 아니라 객체(Object)도 원본을 변경하지 않고 새로운 객체를 만들어야 한다.
const person = { name: "Alice", age: 25 };
// 원본 객체를 직접 수정 ❌
person.age = 30;
console.log(person); // { name: "Alice", age: 30 } (원본이 바뀜)
👉 이 방식은 원본 데이터를 직접 수정해서 불변성을 깨뜨린다.
const person = { name: "Alice", age: 25 };
// 기존 객체를 유지하고 새로운 객체 생성
const newPerson = { ...person, age: 30 };
console.log(person); // { name: "Alice", age: 25 } (원본 유지)
console.log(newPerson); // { name: "Alice", age: 30 } (새로운 객체)
✅ ...spread 연산자를 사용하면 기존 객체를 복사하고 변경할 속성만 수정할 수 있다.
✅ 이 방식이 무결성을 유지하는 올바른 방법이다.
📌 무결성을 유지하는 것이 중요하다.
push(), pop() 대신 concat(), slice() 사용!...spread 연산자 사용!📌 실제로 React, Redux 같은 라이브러리에서는 불변성이 필수!
✅ 배열이나 객체를 변경할 때, 원본을 직접 수정하지 말고 새로운 값을 만들어 사용하자!
✅ 무결성 내장 함수를 활용하면 불변성을 유지하면서 안전하게 데이터를 다룰 수 있다. 🚀