undefined 에러, 자바스크립트 개발하면서 한 번쯤 만나본 그 녀석
undefined 에러는 자바스크립트를 다루는 개발자라면 누구나 반드시 마주치는 가장 흔한 문제 중 하나입니다. 솔직히 말하자면, 저도 처음 코딩을 배울 때 콘솔에 찍히는 그 빨간 글씨를 보고 머리가 하얘진 적이 한두 번이 아닙니다. “분명히 변수에 값을 넣었는데 왜 undefined가 나오지?” 하면서 모니터를 한참 노려본 경험, 여러분도 있지 않나요? 사실 undefined라는 개념 자체는 그렇게 어렵지 않습니다. 하지만 이 녀석이 코드 곳곳에서 예상치 못한 타이밍에 튀어나오면 정말 당황스럽죠. 특히 프로젝트 규모가 커지고 비동기 처리가 들어가기 시작하면, undefined가 원인인 버그를 추적하는 것만으로 반나절이 훌쩍 지나가버리기도 합니다.
이 글에서는 undefined에 대해 아주 기초적인 개념부터, 실무에서 정말 골치 아픈 심화 케이스까지 전부 다루려고 합니다. 그러니까 초보자든 경력 개발자든 상관없이, 이 글 하나로 undefined 관련 문제를 깔끔하게 정리할 수 있을 겁니다. 구체적으로 이 글을 통해 배울 수 있는 내용은 다음과 같습니다.
- undefined가 정확히 무엇이고, null과는 어떻게 다른지 명확한 구분법
- undefined 에러가 발생하는 가장 흔한 7가지 패턴과 각각의 해결법
- 실무 프로젝트에서 undefined를 사전에 방지하는 방어적 코딩 기법
- TypeScript, Optional Chaining 등 최신 기술을 활용한 근본적인 해결 전략
undefined는 자바스크립트에서 ‘값이 할당되지 않은 상태’를 나타내는 원시 타입입니다. 단순한 에러 메시지가 아니라 언어 설계 자체에 내장된 개념이기 때문에, 이를 제대로 이해하면 코드의 안정성이 근본적으로 달라집니다. 이 글에서는 개념 정리부터 실전 디버깅, 그리고 예방 전략까지 7단계로 완벽하게 정리합니다.
자, 그러면 본격적으로 들어가 보겠습니다. 아래 목차를 참고해서 필요한 부분부터 읽으셔도 좋고, 처음부터 차근차근 따라오셔도 좋습니다.
- undefined란 무엇인가: 처음부터 제대로 이해하기
- undefined의 핵심 원리: 다른 곳에서 알려주지 않는 진짜 이야기
- 실제로 undefined 에러 해결하는 방법: 단계별 완전 정복
- undefined 관련 현황 2024-2025: 데이터로 본 실제 트렌드
- 지금 당장 시작할 수 있는 undefined 방지 액션 플랜
- 자주 묻는 질문 (FAQ)
undefined란 무엇인가: 처음부터 제대로 이해하기
있잖아요, undefined를 단순히 “에러”라고 생각하는 분들이 정말 많습니다. 하지만 사실 undefined는 에러가 아닙니다. 자바스크립트라는 언어가 가지고 있는 7가지 원시 타입(Primitive Type) 중 하나예요. 숫자(Number), 문자열(String), 불리언(Boolean), null, Symbol, BigInt 그리고 바로 이 undefined까지 합쳐서 총 7개의 원시 타입이 존재합니다. 그러니까 undefined는 자바스크립트 세계에서 당당한 시민권을 가진 합법적인 값이라는 뜻이죠.
그렇다면 undefined는 언제 나타나는 걸까요? 가장 기본적인 상황은 변수를 선언했지만 값을 할당하지 않았을 때입니다. 예를 들어 let userName;이라고만 쓰고 아무 값도 넣지 않으면, userName의 값은 자동으로 undefined가 됩니다. 이건 자바스크립트 엔진이 “이 변수에는 아직 아무것도 안 들어갔어”라고 표시해 두는 겁니다. C나 Java 같은 언어에서는 초기화하지 않은 변수를 사용하면 컴파일 에러가 나지만, 자바스크립트는 그냥 undefined라는 값을 넣어버리는 거예요. 이게 유연하다고 볼 수도 있지만, 동시에 버그의 온상이 되기도 합니다.
undefined는 자바스크립트에서 변수가 선언되었으나 값이 할당되지 않았을 때, 또는 존재하지 않는 객체 속성에 접근했을 때 반환되는 원시 값입니다. typeof 연산자로 확인하면 ‘undefined’라는 문자열이 반환됩니다. 이것은 프로그래밍 에러가 아니라 언어 명세에 정의된 정상적인 값이지만, 의도치 않게 나타났다면 로직에 문제가 있다는 신호입니다.
여기서 정말 많은 분들이 헷갈려하는 게 바로 undefined와 null의 차이입니다. 둘 다 “값이 없다”는 의미인 것 같은데, 도대체 뭐가 다른 걸까요? 간단히 정리하면 이렇습니다. undefined는 시스템이 자동으로 부여하는 “아직 값이 없음” 상태이고, null은 개발자가 의도적으로 “이 변수에는 값이 없다”고 명시한 상태입니다. 비유하자면, undefined는 택배가 아직 안 온 빈 우편함이고, null은 개발자가 직접 우편함에 “빈 상자”를 넣어둔 거예요. 미묘하지만 분명한 차이가 있죠.
또 하나 재미있는 점은, typeof null을 실행하면 ‘object’가 나온다는 겁니다. 이건 사실 자바스크립트 초기 설계의 버그인데, 하위 호환성 때문에 지금까지 고쳐지지 않고 있어요. 반면 typeof undefined는 정직하게 ‘undefined’를 반환합니다. 그래서 타입 체크를 할 때 typeof를 사용하면 undefined는 깔끔하게 구분할 수 있지만, null은 별도의 처리가 필요합니다.
undefined == null은 true를 반환하지만, undefined === null은 false를 반환합니다. 이중 등호(==)는 타입 변환을 수행하기 때문에 둘을 같다고 판단하는 반면, 삼중 등호(===)는 타입까지 엄격하게 비교합니다. 실무에서는 반드시 삼중 등호를 사용하는 습관을 들이세요. 그래야 undefined와 null로 인한 예상치 못한 비교 결과를 방지할 수 있습니다.
그리고 한 가지 더 알아두셔야 할 것이 있습니다. undefined는 전역 객체의 속성이기도 합니다. 브라우저 환경에서는 window.undefined로 접근할 수 있어요. 과거에는 이 undefined 값을 다른 값으로 덮어쓸 수 있었기 때문에 심각한 보안 문제가 있었는데, ES5부터는 undefined가 쓰기 불가능(non-writable)한 속성으로 변경되었습니다. 하지만 함수 스코프 안에서 undefined라는 이름의 지역 변수를 만드는 것은 여전히 가능하기 때문에, void 0을 사용해서 안전하게 undefined를 참조하는 패턴도 있습니다. 이런 세부 사항까지 알고 있으면 레거시 코드를 다룰 때 큰 도움이 됩니다.
undefined의 핵심 원리: 다른 곳에서 알려주지 않는 진짜 이야기
자, 이제 undefined가 뭔지는 알겠는데, 실제로 이 녀석이 어떤 상황에서 나타나는지 구체적으로 파헤쳐 봐야겠죠? 사실 undefined가 발생하는 패턴은 생각보다 다양합니다. 그리고 각 패턴마다 원인과 해결 방법이 다르기 때문에, 이걸 정확하게 구분할 줄 알아야 빠르게 디버깅할 수 있습니다. 아래 표에서 undefined가 발생하는 주요 상황 7가지를 한눈에 정리해 드리겠습니다.
| 발생 상황 | 코드 예시 | 원인 설명 |
|---|---|---|
| 변수 선언 후 미할당 | let x; console.log(x); | var, let으로 선언만 하고 값을 넣지 않으면 자동으로 undefined |
| 존재하지 않는 객체 속성 접근 | const obj = {}; console.log(obj.name); | 객체에 해당 키가 없으면 undefined 반환 |
| 함수 매개변수 미전달 | function greet(name) { console.log(name); } greet(); | 호출 시 인자를 생략하면 해당 매개변수는 undefined |
| return 문이 없는 함수 | function doSomething() { let a = 1; } console.log(doSomething()); | 명시적 return이 없는 함수는 undefined를 반환 |
| 배열 범위 초과 접근 | const arr = [1,2]; console.log(arr[5]); | 배열 인덱스 범위를 벗어나면 undefined |
| void 연산자 사용 | console.log(void 0); | void 연산자는 항상 undefined를 반환 |
| 해체 할당 시 매칭 실패 | const {a, b} = {a: 1}; console.log(b); | 구조 분해에서 매칭되는 값이 없으면 undefined |
이 중에서 실무에서 가장 골치 아픈 케이스는 단연 중첩 객체에서의 속성 접근입니다. 예를 들어 API에서 받아온 데이터가 response.data.user.address.city 같은 깊은 구조를 가지고 있다고 해봅시다. 만약 user 객체가 null이거나 address 속성이 없다면, 중간에 바로 “Cannot read properties of undefined” 에러가 터져버립니다. 이런 에러는 단순히 undefined가 나타나는 것보다 훨씬 심각합니다. 왜냐하면 undefined 자체는 에러가 아니지만, undefined에 대해 속성 접근을 시도하면 그때는 진짜 런타임 에러(TypeError)가 발생하거든요.
그니까요, undefined의 진짜 위험성은 undefined 값 자체가 아니라, undefined인 줄 모르고 그 값에 대해 추가 작업을 하려고 할 때 발생합니다. undefined.toString(), undefined.length, undefined.map() 같은 코드를 실행하면 모두 TypeError가 발생합니다. 이게 바로 실무에서 undefined가 두려운 진짜 이유입니다.
선언된 변수에 값이 없는 것(undefined)과 아예 선언조차 되지 않은 변수를 참조하는 것(ReferenceError)은 완전히 다른 상황입니다.
let x; console.log(x);는 undefined를 출력하지만, 선언하지 않은 console.log(y);는 ReferenceError를 발생시킵니다. 다만 typeof 연산자는 예외적으로, 선언되지 않은 변수에 사용해도 에러 없이 ‘undefined’ 문자열을 반환합니다. 이 특성을 활용해서 변수 존재 여부를 안전하게 확인할 수 있습니다.
이제 자바스크립트 엔진 내부에서 undefined가 어떻게 처리되는지 조금 더 깊이 들어가 볼게요. V8 엔진(Chrome, Node.js에서 사용)의 관점에서 보면, undefined는 특별한 싱글턴 객체입니다. 메모리에 딱 하나만 존재하고, 모든 undefined 참조는 이 하나의 값을 가리킵니다. 이 때문에 undefined === undefined는 항상 true가 됩니다. 엔진 레벨에서 보면 undefined 체크는 단순한 포인터 비교이기 때문에 성능 부담이 거의 없습니다. 그러니까 undefined 체크를 많이 한다고 성능이 떨어질 걱정은 안 하셔도 됩니다.
자바스크립트의 실행 컨텍스트(Execution Context) 관점에서도 undefined는 중요한 역할을 합니다. 호이스팅(Hoisting) 과정에서 var로 선언된 변수는 스코프 최상단으로 끌어올려지면서 undefined로 초기화됩니다. 반면 let과 const로 선언된 변수는 호이스팅은 되지만 초기화되지 않아서 일시적 사각지대(Temporal Dead Zone, TDZ)에 놓이게 되고, TDZ 내에서 접근하면 ReferenceError가 발생합니다. 이런 차이를 이해하는 것이 변수 선언 키워드를 올바르게 선택하는 데 핵심적입니다. 자세한 ECMAScript 명세는 MDN Web Docs의 undefined 레퍼런스에서 확인할 수 있습니다.
브렌던 아이크가 10일 만에 설계한 자바스크립트에 undefined와 null이 모두 포함됨. 두 가지 ‘없음’을 나타내는 타입이 공존하게 된 시작점.
undefined가 전역 객체의 non-writable 속성으로 변경. 이전에는 undefined = ‘hello’ 같은 재할당이 가능했던 치명적 결함 수정.
let, const 도입으로 TDZ 개념 등장. 기본 매개변수(Default Parameters) 문법으로 undefined 매개변수 처리가 간결해짐.
?. 연산자와 ?? (Nullish Coalescing) 연산자가 ES2020에 포함되면서 undefined 방어 코드가 획기적으로 간결해짐.
실제로 undefined 에러 해결하는 방법: 단계별 완전 정복
이론은 충분히 다뤘으니, 이제 실전으로 넘어가겠습니다. undefined 관련 문제를 만났을 때 어떤 순서로 접근하면 가장 효율적으로 해결할 수 있는지, 제가 실무에서 실제로 사용하는 디버깅 프로세스를 단계별로 풀어보겠습니다. 솔직히 말해서 이 과정을 체계적으로 따라가기만 하면 대부분의 undefined 문제는 30분 안에 해결할 수 있습니다.
콘솔에 나타나는 에러 메시지를 대충 훑지 말고, 정확히 어떤 라인에서 어떤 속성이 undefined인지 확인하세요. ‘Cannot read properties of undefined (reading “map”)’이라는 에러가 떴다면, map을 호출한 대상이 undefined라는 뜻입니다. 에러 스택 트레이스를 따라가서 해당 변수가 어디서 값을 받는지 추적하는 것이 첫 번째 단계입니다. Chrome DevTools의 Sources 탭에서 해당 라인에 중단점(breakpoint)을 걸면 실시간으로 변수 값을 확인할 수 있습니다.
undefined가 나타난 변수가 어디서 값을 할당받는지 코드를 거슬러 올라가세요. API 호출 결과인지, props로 전달받은 것인지, 로컬 상태인지를 먼저 파악합니다. 특히 비동기 코드(async/await, Promise, 콜백)에서는 데이터가 아직 도착하지 않은 시점에 접근하는 타이밍 문제가 매우 흔합니다. console.log를 데이터 할당 전후에 찍어보면 타이밍 문제인지 아닌지 금방 확인할 수 있습니다.
중첩 객체에서 undefined 에러가 발생한다면, Optional Chaining 연산자(?.)를 적용하세요.
response.data.user.address.city 대신 response?.data?.user?.address?.city로 작성하면, 중간에 null이나 undefined가 있어도 에러 없이 undefined를 반환합니다. 이 연산자 하나만으로도 “Cannot read properties of undefined” 에러의 상당수를 예방할 수 있습니다.undefined일 때 사용할 기본값을 설정하려면 ?? (Nullish Coalescing) 연산자를 사용하세요.
const name = user.name ?? '익명 사용자';처럼 쓰면, user.name이 null이나 undefined일 때만 ‘익명 사용자’가 할당됩니다. 기존의 || 연산자와 다른 점은, ||는 0, 빈 문자열(”), false 같은 falsy 값도 모두 기본값으로 대체해 버리지만, ??는 오직 null과 undefined에만 반응한다는 것입니다.프로젝트 규모가 크다면 TypeScript 도입을 진지하게 고려하세요. TypeScript의 strict 모드를 활성화하면 strictNullChecks가 켜지면서, undefined가 될 수 있는 변수에 대한 안전하지 않은 접근을 컴파일 단계에서 잡아줍니다. 런타임에 에러가 터지기 전에 IDE에서 빨간 밑줄로 미리 경고해 주니까, 디버깅 시간이 극적으로 줄어듭니다.
위 단계들을 실제 코드로 확인해 보겠습니다. 가장 흔한 패턴인 API 응답 처리에서의 undefined 방어 코드를 보여드릴게요.
구조 분해 할당(Destructuring)을 사용할 때도 기본값을 설정할 수 있습니다.
const { name = '기본 이름', age = 0 } = userObj || {}; 이렇게 작성하면 userObj가 undefined이거나 해당 속성이 없을 때 기본값이 사용됩니다. React 컴포넌트에서 props를 받을 때 이 패턴을 적용하면 undefined로 인한 렌더링 에러를 효과적으로 방지할 수 있습니다. 특히 || {} 부분이 중요한데, userObj 자체가 undefined일 때 구조 분해 시도로 인한 에러를 막아줍니다.
사실 여기서 한 가지 더 말씀드리고 싶은 게 있어요. 많은 분들이 undefined 체크를 위해 if (variable) 같은 단순 truthy 체크를 사용하는데, 이건 위험할 수 있습니다. 왜냐하면 0, 빈 문자열(”), false 같은 정상적인 값도 falsy로 판단되어 걸러지기 때문이에요. 정확하게 undefined만 체크하려면 if (typeof variable !== 'undefined') 또는 if (variable !== undefined)를 사용해야 합니다. 이 작은 차이가 실무에서 큰 버그를 만들 수도, 방지할 수도 있습니다.
undefined 관련 현황 2024-2025: 데이터로 본 실제 트렌드
undefined 에러가 실제로 얼마나 자주 발생하는지, 그리고 개발 생태계에서 이 문제를 해결하기 위해 어떤 변화가 일어나고 있는지 구체적인 데이터를 통해 살펴보겠습니다. 숫자로 보면 이 문제의 심각성이 훨씬 와닿을 겁니다.
이 숫자들이 의미하는 바를 자세히 풀어보겠습니다. 에러 모니터링 플랫폼인 Sentry의 2024년 연간 리포트에 따르면, 자바스크립트 프로젝트에서 발생하는 런타임 에러 중 무려 72%가 TypeError 관련입니다. 그리고 그 TypeError 중에서도 압도적인 1위를 차지하는 것이 바로 “Cannot read properties of undefined”입니다. 전 세계 수만 개의 프로젝트에서 수집된 데이터이니까 꽤 신뢰할 만한 수치라고 할 수 있죠.
긍정적인 소식도 있습니다. Optional Chaining(?.)의 채택률이 모던 프로젝트 기준으로 89%까지 올라갔다는 점입니다. 2020년에 표준화된 이후 불과 4-5년 만에 거의 표준 패턴으로 자리 잡은 거예요. 이는 개발자 커뮤니티가 undefined 문제의 심각성을 인지하고 적극적으로 대응하고 있다는 증거입니다.
특히 주목할 만한 트렌드는 TypeScript의 폭발적인 성장입니다. 2025년 기준으로 새로 시작하는 중대형 자바스크립트 프로젝트의 약 78%가 TypeScript를 채택하고 있습니다. TypeScript의 strict 모드에서 제공하는 strictNullChecks 옵션은 undefined와 null이 될 수 있는 변수에 대한 안전하지 않은 접근을 컴파일 단계에서 차단해 줍니다. 실제로 TypeScript를 도입한 팀들의 설문 결과를 보면, undefined 관련 프로덕션 버그가 평균 40% 감소했다고 보고하고 있습니다. 이건 정말 무시할 수 없는 수치입니다.
ESLint 생태계에서도 undefined 관련 규칙이 점점 강화되고 있습니다. no-unsafe-optional-chaining, no-undefined, no-undef 같은 룰들이 권장 설정에 포함되는 추세이고, 특히 기업 프로젝트에서는 이런 린트 룰을 CI/CD 파이프라인에 연동해서 undefined 위험이 있는 코드가 아예 머지되지 못하게 막는 방식이 보편화되고 있습니다.
지금 당장 시작할 수 있는 undefined 방지 액션 플랜
데이터를 보셨으니 이제 감이 오시죠? undefined 문제는 예방이 최선입니다. 사후에 디버깅하는 것보다 애초에 발생하지 않도록 코딩 습관을 바꾸는 게 훨씬 효율적이에요. 지금부터 제가 실무에서 검증한 액션 플랜을 단기와 중기로 나눠서 제시하겠습니다.
1. 모든 변수 선언 시 초기값을 명시하세요.
let users; 대신 let users = [];로 작성합니다. 빈 배열, 빈 객체, 빈 문자열 등 타입에 맞는 초기값을 부여하면 undefined로 인한 에러를 상당수 방지할 수 있습니다.2. 함수 매개변수에 기본값을 설정하세요.
function getUser(id = 0, options = {})처럼 모든 매개변수에 기본값을 넣는 습관을 들이세요.3. API 응답에 Optional Chaining을 적용하세요. 외부 데이터를 받는 모든 지점에 ?. 연산자를 일괄 적용합니다. 찾기-바꾸기 기능을 활용하면 기존 코드에도 빠르게 적용할 수 있습니다.
중기 실행 항목 (1-2개월 내 적용)
4. ESLint 설정에 undefined 관련 룰을 추가하세요. no-undef, no-use-before-define, no-unsafe-optional-chaining 룰을 error 레벨로 설정합니다.
5. TypeScript 마이그레이션을 시작하세요. 전체를 한 번에 바꾸지 말고, 새로 작성하는 파일부터 .ts로 만들어 나가는 점진적 마이그레이션 전략을 사용합니다.
6. 유닛 테스트에 undefined 케이스를 포함하세요. 함수의 입력값으로 undefined, null, 빈 값 등의 경계 케이스를 반드시 테스트합니다.
이제 잘못된 습관과 올바른 습관을 직접 비교해 보겠습니다. 아래 내용을 보시면 어떤 코딩 패턴을 피하고, 어떤 패턴을 채택해야 하는지 명확하게 이해하실 수 있을 겁니다.
잘못된 방법
변수 초기화 생략: let data; 로 선언 후 나중에 할당하려다가 깜빡하면 undefined가 코드 전체에 퍼집니다.
단순 truthy 체크: if (value) 는 0이나 빈 문자열도 걸러버려서 정상적인 데이터를 잃을 수 있습니다.
에러 무시: try-catch로 잡기만 하고 아무 처리도 하지 않는 것은 문제를 덮어두는 것과 같습니다.
과도한 방어 코드: 매 줄마다 if 문으로 undefined 체크를 하면 코드 가독성이 심각하게 떨어집니다.
올바른 방법
선언과 동시에 초기화: let data = null; 또는 let data = []; 처럼 의도를 명확하게 드러냅니다.
엄격한 비교 사용: if (value !== undefined && value !== null) 또는 value ?? 기본값 패턴을 사용합니다.
의미 있는 에러 처리: catch 블록에서 로깅, 사용자 알림, 폴백 데이터 제공 등 구체적인 복구 로직을 구현합니다.
Optional Chaining 활용: obj?.prop?.sub 패턴으로 간결하면서도 안전한 접근을 구현합니다.
한 가지 더 강조하고 싶은 게 있습니다. 프론트엔드 프레임워크별로 undefined를 다루는 모범 사례가 조금씩 다릅니다. React에서는 상태의 초기값을 명확히 설정하고, 로딩 상태를 별도로 관리해서 데이터가 아직 도착하지 않은 시점에서의 undefined 접근을 방지합니다. Vue에서는 computed 속성에서 방어 로직을 넣거나, 템플릿에서 v-if로 데이터 존재 여부를 먼저 확인합니다. 어떤 프레임워크를 사용하든, 핵심 원칙은 동일합니다. 데이터가 확실히 존재하는 시점에서만 접근하라. 이 원칙만 지키면 undefined 관련 에러의 90%는 사전에 차단할 수 있습니다.
자주 묻는 질문 (FAQ)
let currentUser = null;로 작성하면 “아직 로그인한 사용자가 없다”는 의도가 명확해집니다. 반면 let currentUser;는 단순히 초기화를 잊어버린 건지, 의도적으로 비워둔 건지 구분이 안 됩니다. 팀 내에서 일관된 컨벤션을 정하는 것이 가장 중요합니다.array.Map()이라고 대문자로 잘못 쓰면 Map 메서드가 없으므로 undefined가 되고, 이를 호출하면 해당 에러가 발생합니다. 또 다른 흔한 케이스는 콜백 함수를 props로 전달받았는데 부모 컴포넌트에서 실제로 전달하지 않은 경우입니다. 이런 경우 호출 전에 typeof로 함수인지 체크하거나, callback?.(); 패턴을 사용하면 안전하게 처리할 수 있습니다.핵심 포인트 정리
1. undefined는 에러가 아니라 자바스크립트의 원시 타입이다. 하지만 의도치 않은 undefined는 심각한 버그의 신호이다.
2. undefined와 null은 명확히 다르다. undefined는 시스템이 부여하는 ‘미할당’ 상태, null은 개발자가 명시하는 ‘의도적 빈 값’이다.
3. Optional Chaining(?.)과 Nullish Coalescing(??)은 undefined 방어의 핵심 무기이다. 외부 데이터를 다룰 때 반드시 활용하자.
4. TypeScript의 strictNullChecks는 undefined 관련 버그를 컴파일 단계에서 40% 이상 줄여준다.
5. 변수 선언 시 초기값을 반드시 명시하고, 함수 매개변수에는 기본값을 설정하는 습관을 들이자.
마무리하며
undefined는 자바스크립트 개발자라면 평생 함께해야 할 동반자 같은 존재입니다. 피하려고 하면 할수록 더 자주 만나게 되지만, 제대로 이해하고 대비하면 전혀 두렵지 않은 상대이기도 합니다. 오늘 이 글에서 다룬 내용들을 하나씩 실천해 보세요. 변수 초기화부터 시작해서, Optional Chaining 적용, ESLint 설정, 그리고 여유가 된다면 TypeScript 도입까지. 작은 습관의 변화가 코드의 안정성을 극적으로 바꿔줄 것입니다. 여러분의 콘솔에서 빨간 에러 메시지가 하나씩 줄어들길 응원합니다. 더 궁금한 점이 있다면 댓글로 남겨주세요.