Identifier has already been declared 오류 원인과 중복 선언 해결 방법
자바스크립트를 실행하다가 SyntaxError: Identifier '변수명' has already been declared라는 오류가 나타날 때가 있습니다. 코드를 조금 수정했을 뿐인데 갑자기 실행 자체가 되지 않아 당황하기 쉬운 오류인데요.
Identifier has already been declared 오류는 대부분 같은 스코프에서 동일한 이름을 중복 선언했을 때 발생합니다. 특히 let과 const, import 문을 사용할 때 자주 만날 수 있습니다.
중복 선언이 정확히 무엇인지부터 재할당과의 차이, 상황별 해결 방법까지 알아보겠습니다.
Identifier has already been declared 뜻은?
Identifier는 변수, 함수, 클래스 등 코드에서 사용하는 이름을 의미합니다. 이미 같은 영역에서 사용 중인 이름을 다시 선언하려고 하면 자바스크립트가 중복을 발견하고 SyntaxError를 발생시킬 수 있습니다.
let userName = "민수";
let userName = "지민";
// SyntaxError:
// Identifier 'userName' has already been declared
첫 번째 줄에서 이미 userName을 선언했는데 같은 스코프에서 다시 let userName을 선언했기 때문입니다. 해결의 핵심은 어디에서 같은 이름이 먼저 선언됐는지 찾는 것입니다.
let·const 중복 선언이 가장 흔한 원인
let과 const는 같은 스코프에서 동일한 이름으로 다시 선언할 수 없습니다. const끼리뿐 아니라 let과 const를 섞어서 선언해도 충돌할 수 있습니다.
const count = 10;
const count = 20; // 오류
let score = 80;
const score = 100; // 오류
코드가 길어지면 위쪽에서 이미 변수를 선언했다는 사실을 놓치기 쉽습니다. 오류 메시지에 표시된 변수명을 프로젝트 전체에서 검색하면 최초 선언 위치를 빠르게 찾을 수 있습니다.
중복 선언과 재할당은 다릅니다
초보자라면 재선언과 재할당을 구분하는 것이 중요합니다. 재선언은 변수 이름을 다시 만드는 것이고, 재할당은 이미 존재하는 변수에 새로운 값을 넣는 것입니다.
// 중복 선언 - 오류
let count = 1;
let count = 2;
// 재할당 - 가능
let count = 1;
count = 2;
값만 변경하려는 목적이라면 두 번째 let을 다시 작성할 필요가 없습니다. 이미 선언된 변수라면 변수명에 새로운 값을 할당하면 됩니다.
단, const는 재선언뿐 아니라 재할당도 허용되지 않습니다. const 값을 다시 대입하면 앞서 살펴본 Assignment to constant variable 오류와 연결될 수 있습니다.
블록 스코프를 확인해야 하는 이유
같은 변수 이름이라고 해서 항상 오류가 발생하는 것은 아닙니다. let과 const는 블록 스코프를 가지므로 서로 다른 블록이라면 같은 이름을 별도로 사용할 수 있습니다.
let message = "바깥";
if (true) {
let message = "안쪽";
console.log(message);
}
console.log(message);
위 코드의 두 message는 서로 다른 스코프에 있으므로 중복 선언 오류가 발생하지 않습니다. 따라서 변수 이름만 찾지 말고 같은 중괄호 영역 안에서 선언됐는지도 함께 확인해야 합니다.
import 때문에 Identifier 오류가 발생하는 경우
ES Module을 사용한다면 import로 가져온 이름과 현재 파일에서 선언한 변수명이 충돌할 수도 있습니다. import한 이름 역시 현재 모듈에서 사용하는 식별자이기 때문입니다.
import { user } from "./user.js";
const user = {
name: "민수"
};
// 중복 이름 문제
이럴 때는 불필요한 선언을 제거하거나 import할 때 별칭을 지정할 수 있습니다.
import { user as importedUser } from "./user.js";
const user = {
name: "민수"
};
프로젝트가 커질수록 data, user, result처럼 범용적인 이름이 충돌하기 쉬우므로 의미가 분명한 변수명을 사용하는 것도 도움이 됩니다.
함수·클래스 이름 충돌도 확인하세요
중복 선언 문제를 찾을 때 변수만 확인해서는 안 됩니다. 같은 스코프에서 함수나 클래스 등 다른 선언과 이름이 충돌하는 경우도 살펴봐야 합니다.
class User {
}
const User = "민수";
오류 메시지에 특정 이름이 표시된다면 프로젝트 검색 기능을 이용해 해당 이름이 let, const, class, import 등으로 어디에서 선언되고 있는지 확인해 보세요.
코드를 복사한 뒤 발생하는 중복 선언
예제 코드를 테스트하다 같은 내용을 두 번 붙여넣으면서 중복 선언이 생기는 경우도 흔합니다. 특히 브라우저 콘솔, 온라인 코드 실행 환경, 하나의 파일에 여러 예제를 합쳐 놓았을 때 쉽게 발생합니다.
const API_VERSION = "v1";
// 다른 코드를 붙여넣은 뒤...
const API_VERSION = "v1";
각각 따로 실행했을 때는 정상인 코드라도 하나의 스코프에 합치면 이름이 충돌할 수 있습니다. 예제를 합쳤다면 변수와 함수 이름이 겹치는지 확인해 보세요.
script 파일을 여러 번 불러온 경우는?
HTML에서 같은 자바스크립트 파일을 실수로 중복해서 포함하거나 여러 스크립트가 전역 영역에서 같은 이름을 선언하는 구조도 점검할 필요가 있습니다. 여러 파일을 하나의 페이지에 추가하면서 전역 이름이 겹치면 예상하지 못한 충돌이 생길 수 있습니다.
개발자 도구의 Network 탭과 HTML의 script 태그를 확인하고, 동일 파일이 의도치 않게 여러 경로에서 로드되는 것은 아닌지 살펴보세요. 모듈 구조를 적절하게 사용해 전역 영역에 불필요한 이름을 만드는 일을 줄이는 것도 좋은 방법입니다.
Identifier has already been declared 주요 원인 7가지
1. 같은 스코프에서 let을 두 번 선언한 경우
2. 동일한 이름의 const를 다시 선언한 경우
3. let과 const가 같은 이름으로 충돌한 경우
4. import한 이름과 로컬 선언 이름이 같은 경우
5. 함수·클래스 등 다른 선언과 이름이 충돌한 경우
6. 코드를 복사하면서 같은 선언이 두 번 들어간 경우
7. 여러 스크립트의 전역 선언이 충돌하는 경우
공통점은 이미 사용 중인 식별자를 동일한 선언 영역에서 다시 만들려고 한다는 것입니다. 오류가 난 줄만 수정하기보다 해당 이름의 첫 번째 선언까지 함께 확인해야 정확하게 해결할 수 있습니다.
중복 선언 오류 해결 순서
먼저 콘솔에 표시된 Identifier 이름을 확인하세요. 그 이름을 현재 파일뿐 아니라 프로젝트 전체에서 검색하면 중복 선언 위치를 찾기 쉬워집니다.
| 순서 | 확인할 내용 |
| 1단계 | 오류 메시지에 표시된 변수명 확인 |
| 2단계 | 프로젝트 전체에서 같은 이름 검색 |
| 3단계 | 각 선언이 같은 스코프인지 확인 |
| 4단계 | 재선언인지 단순 재할당인지 구분 |
| 5단계 | import·함수·클래스 이름 충돌 확인 |
| 6단계 | 불필요한 선언 삭제 또는 이름 변경 |
| 7단계 | 스크립트 중복 로딩 여부까지 확인 |
var로 바꾸면 해결되는 걸까?
검색하다 보면 오류를 없애기 위해 let을 var로 변경하는 방법을 발견할 수 있습니다. 일부 상황에서는 에러 메시지가 사라질 수 있지만 중복 선언의 원인을 해결하지 않고 var로 바꾸는 것은 권장할 만한 해결법이 아닙니다.
원래 하나만 있어야 하는 변수를 두 번 선언한 것이라면 중복 코드를 제거하는 것이 먼저입니다. 값 변경이 목적이라면 재선언하지 말고 재할당하고, 서로 다른 값이라면 각각 의미가 분명한 이름을 사용하는 편이 코드를 관리하기 쉽습니다.
Identifier 중복 선언을 예방하는 방법
변수 이름을 지나치게 짧거나 범용적으로 작성하면 프로젝트가 커질수록 충돌 가능성이 높아집니다. 변수의 역할이 드러나는 이름을 사용하고 같은 스코프에서 이미 선언된 이름인지 확인하는 습관을 들여보세요.
Identifier has already been declared는 결국 이미 선언된 이름을 같은 스코프에서 다시 선언하려고 했다는 신호입니다. let과 const의 중복 선언을 먼저 확인하고 문제가 없다면 import, 함수·클래스 이름, 복사한 코드와 스크립트 구조까지 범위를 넓혀 살펴보세요.
재선언과 재할당의 차이만 확실하게 이해해도 이 오류를 크게 줄일 수 있습니다. 값을 바꾸고 싶은 것인지 새로운 변수를 만들고 싶은 것인지 먼저 구분하면 해결 방법도 훨씬 명확해집니다.