본문 바로가기
IT

Assignment to constant variable — const 재할당 원인·해결·예방

by 샤나엘 2026. 7. 1.
반응형

Assignment to constant variable — const 재할당 원인·해결·예방

자바스크립트에서 "TypeError: Assignment to constant variable."이 뜨면, const로 선언한 변수에 값을 다시 대입하려 했다는 뜻이다. const는 "상수(constant)", 즉 한 번 값을 정하면 다른 값으로 바꿀 수 없는 변수라 재할당이 금지된다. 그런데 여기서 많은 사람이 헷갈리는 지점이 있다. const 배열에 push는 되는데 왜 재대입은 안 되느냐는 것이다. 핵심은 const가 막는 건 "변수와 값의 연결(재할당)"이지 "값 내부의 변경"이 아니라는 데 있다. 그래서 const 객체의 속성을 바꾸거나 배열에 요소를 넣는 건 되지만, 그 변수 자체에 새 객체·배열을 통째로 대입하는 건 안 된다. 이 글은 이 에러의 의미, 재할당과 변경의 차이, 원인과 해결을 정리한다.

 

Assignment to constant variable

이 글의 구성

 

🔎에러 메시지의 의미
⚖️재할당 vs 변경(mutation)
🧩자주 나오는 발생 원인 4가지
💻재현과 진단
🛠해결 — const와 let 고르기
💬자주 묻는 질문 5가지

🔎 에러 메시지의 의미

const는 "재할당 불가능한 변수"를 선언하는 키워드다. const로 이름과 값을 한 번 묶으면, 그 이름에 다른 값을 다시 대입할 수 없다. 그렇게 하려 하면 자바스크립트가 "상수 변수에 대입했다"며 TypeError를 던진다. 그래서 이 에러는 대부분 원인이 명확하다. const로 선언한 무언가에 = 로 새 값을 넣으려 한 것이다.

 

메시지 자체는 어느 변수인지 이름을 콕 집어 주지 않지만, 콘솔의 스택 추적을 보면 몇 번째 줄에서 났는지 나온다. 그 줄의 대입식 왼쪽에 있는 변수가 const로 선언됐는지 확인하면 된다. 값을 바꿔야 하는 변수를 const로 선언해 둔 게 대부분의 사연이다.

핵심 — const는 "재할당"을 막는다

const가 잠그는 건 변수와 값의 연결이다. 즉 그 이름이 다른 값을 가리키도록 바꾸는 걸 막는다. 하지만 그 값이 객체나 배열이면, 값 내부를 바꾸는 건 막지 않는다. 그래서 재할당(= 로 새 값)은 에러지만, 변경(속성 수정·push)은 허용된다. 이 둘을 구분하는 게 이 에러를 이해하는 핵심이다.


⚖️ 재할당 vs 변경(mutation)

이 에러에서 가장 많이 헷갈리는 지점이다. const 배열에 push는 되는데 재대입은 안 되는 이유가 여기 있다.

동작 const에서
재할당 obj = {} / arr = [] / x = 5 ✗ TypeError
속성 변경 obj.name = "..." / obj.age++ ✓ 허용
배열 변경 arr.push(1) / arr[0] = 2 ✓ 허용

const 변수가 객체나 배열을 가리킬 때, 그 변수는 "그 객체를 가리킨다"는 연결만 고정된다. 그 객체 안의 속성을 바꾸거나 배열에 요소를 더하는 건 연결을 바꾸는 게 아니라 값 내부를 바꾸는 것이라 허용된다. 반면 obj = 새객체처럼 변수가 다른 객체를 가리키게 하는 건 연결 자체를 바꾸는 재할당이라 막힌다. 한마디로 "상자 안 내용물은 바꿔도 되지만, 상자를 다른 걸로 통째 교체할 순 없다"는 규칙이다.


🧩 자주 나오는 발생 원인 4가지

원인 1 — const 변수에 직접 재대입

가장 흔하다. const count = 0으로 선언해 놓고 나중에 count = 1처럼 새 값을 넣은 경우다. 값이 바뀌어야 하는 변수를 습관적으로 const로 선언한 데서 온다.

원인 2 — ++·+= 같은 복합 대입

const 숫자 변수에 count++나 count += 1을 쓴 경우다. 이런 연산도 결국 변수에 새 값을 다시 넣는 재할당이라 막힌다. 카운터·누적 변수를 const로 둔 실수다.

원인 3 — 반복문 카운터를 const로

for (const i = 0; ...; i++)처럼 증가하는 카운터를 const로 선언한 경우다. i++에서 재할당이 일어나 터진다. 다만 for...of의 요소 변수는 매 반복마다 새로 바인딩돼 const로 써도 된다.

원인 4 — 값을 바꾸려다 통째로 재할당

const 배열의 내용을 비우려고 arr = []로 새 배열을 대입하거나, 객체를 갈아끼우려 obj = {...}로 통째 대입한 경우다. 내부만 바꾸면 될 걸 연결까지 바꾸려다 막힌다.


💻 재현과 진단

전형적인 재현이다. const 변수에 새 값을 대입하면 즉시 터진다.

// const 변수 재할당
const count = 0;
count = 1;
// ✗ TypeError: Assignment to constant variable.

// ++ 도 재할당이라 막힘
count++;
// ✗ TypeError: Assignment to constant variable.

진단은 단순하다. 콘솔의 스택 추적으로 에러가 난 줄을 찾아, 그 대입식 왼쪽 변수가 어디서 const로 선언됐는지 거슬러 올라간다. 그 변수가 값을 바꿔야 하는 성격이라면 선언을 let으로 바꾸면 되고, 값 내부만 바꾸면 되는 거라면 대입이 아니라 변경으로 코드를 고친다.

// ✓ 객체·배열 내부 변경은 const로도 OK
const user = { name: "김개발" };
user.name = "이코딩";   // 속성 변경 → 허용

const list = [];
list.push(1);            // 배열 변경 → 허용

🛠 해결 — const와 let 고르기

해결의 갈림길은 "재할당이 필요한가"다. 필요하면 let, 아니면 const를 유지한 채 변경으로 처리한다.

상황 해결
값을 다시 대입해야 함 const → let 으로 선언 변경(재할당 허용)
카운터·누적 변수 let으로 선언해 ++·+= 사용
반복문 카운터 for는 let (i++), for...of 요소는 const 가능
객체·배열 내용만 변경 const 유지, 속성 수정·push 등 변경으로 처리
배열을 비우고 싶음 arr = [] 대신 arr.length = 0 또는 arr.splice(0)

기본 습관은 "일단 const, 재할당이 필요할 때만 let"이 널리 권장된다. const가 기본이면 값이 실수로 바뀌는 걸 막아 주고, let으로 선언된 변수만 "이건 바뀔 수 있다"고 눈에 띄게 표시해 준다. 이 에러가 났다는 건 그 변수가 사실은 바뀌어야 하는 변수였다는 뜻이니, let으로 바꾸거나 변경 방식으로 고치면 된다.

// ✓ 재할당이 필요하면 let
let count = 0;
count++;                 // OK

// ✓ 배열을 비울 때 (재할당 없이)
const list = [1, 2, 3];
list.length = 0;         // 재할당 아니라 변경 → OK

💬 자주 묻는 질문 5가지

Q1const 배열에 push는 왜 되나요?

const가 막는 건 변수와 값의 연결(재할당)이지, 값 내부의 변경이 아니기 때문입니다. push는 배열이라는 값 안에 요소를 더하는 변경이라 허용됩니다. 반면 arr = [1,2]처럼 변수가 다른 배열을 가리키게 하면 연결을 바꾸는 재할당이라 막힙니다.

Q2const를 let으로 바꾸면 되나요?

재할당이 정말 필요한 변수라면 그게 맞습니다. 다만 값 내부만 바꾸면 되는 거라면 굳이 let으로 바꿀 필요 없이 속성 수정·push 같은 변경으로 처리하는 게 낫습니다. 이 에러는 "이 변수가 사실 바뀌어야 하는가"를 다시 묻게 해주는 신호이기도 합니다.

Q3for 반복문에서 나요.

for (const i = 0; i < n; i++)처럼 증가 카운터를 const로 선언한 경우입니다. i++에서 재할당이 일어나 터지죠. 일반 for는 let (i)를 쓰세요. 단 for...of는 반복마다 요소 변수가 새로 바인딩되므로 const로 써도 됩니다.

Q4const 배열을 비우고 싶어요.

arr = []는 재할당이라 막힙니다. 대신 arr.length = 0으로 길이를 0으로 만들거나 arr.splice(0)로 전체를 제거하면 됩니다. 둘 다 변수의 연결은 그대로 두고 배열 내용만 바꾸는 변경이라 const에서도 동작합니다.

Q5const 객체를 진짜 못 바꾸게 하려면?

const만으로는 내부 변경을 막지 못합니다. 값 자체를 얼리고 싶다면 Object.freeze(obj)를 쓰면 속성 추가·수정이 막힙니다. 다만 이건 얕은(shallow) 동결이라 중첩된 객체 안쪽까지 막지는 않는다는 점은 알아 두세요.


📌 결론

"Assignment to constant variable."은 const로 선언한 변수에 값을 다시 대입하려다 나는 TypeError다. const는 변수와 값의 연결(재할당)을 고정할 뿐, 그 값이 객체·배열이면 내부 변경까지 막지는 않는다. 그래서 push·속성 수정은 되고, 통째 재대입은 안 된다.

 

실무 원칙은 다음과 같다.

 

🔒 const의 범위를 이해한다. const가 막는 건 재할당(= 로 새 값)이지, 객체·배열 내부의 변경이 아니다. 이 구분이 이 에러의 전부다.

🔄 재할당이 필요하면 let. 값을 다시 대입하거나 ++·+=를 써야 하는 변수, 일반 for 카운터는 let으로 선언한다.

🧱 변경이면 그대로. 값 내부만 바꾸면 되는 경우 const를 유지하고 속성 수정·push·length = 0 같은 변경으로 처리한다.

const 재할당 에러 체크리스트

 

01에러 난 줄의 대입식 왼쪽 변수가 const 선언인지 확인.
02재할당(= 새 값)인지 내부 변경(속성·push)인지 구분.
03재할당이 필요하면 const → let 으로 변경.
04++·+= 쓰는 카운터·누적 변수는 let으로.
05배열 비우기는 arr = [] 대신 length = 0·splice(0).
06기본은 const, 바뀌는 변수만 let으로 표시.

본 글은 자바스크립트 TypeError(const 재할당)의 일반적 원인과 해결 방법을 정리한 자료다. 코드 수정은 영향 범위를 확인한 뒤 신중히 적용한다.

 

#JavaScript #TypeError #Assignmenttoconstant #const재할당 #자바스크립트에러 #const #let #변수선언 #재할당 #mutation #Objectfreeze #반복문 #프론트엔드 #JS디버깅 #웹개발

반응형

댓글