2025-09-04 23:45

  • 자바스크립트에서 undefined는 값이 할당되지 않은 변수의 상태를 나타내는 원시 자료형입니다.

  • undefined는 의도적으로 값이 없음을 의미하는 null과는 다르며, 함수가 값을 반환하지 않거나 객체에 없는 속성에 접근할 때 등 다양한 상황에서 발생합니다.

  • 옵셔널 체이닝(?.)이나 널리쉬 병합 연산자(??)와 같은 최신 문법을 활용하여 undefined로 인한 에러를 효과적으로 방지하고 안정적인 코드를 작성할 수 있습니다.

자바스크립트 undefined 완벽 정복 핸드북 에러 없는 코딩의 시작

혹시 자바스크립트 코드를 작성하다가 TypeError: Cannot read properties of undefined 라는 에러 메시지를 마주하고 당황한 적이 있으신가요? 개발자라면 누구나 한 번쯤은 겪어봤을 이 에러의 주범, 바로 undefined입니다. 많은 개발자들이 undefined를 그저 ‘정의되지 않음’이라는 막연한 개념으로 이해하고 넘어가지만, 이 친구의 정체를 정확히 알지 못하면 코드 곳곳에 숨겨진 지뢰를 밟게 될 수 있습니다.

이 핸드북은 undefined에 대한 모든 것을 담았습니다. undefined가 왜 만들어졌는지 그 탄생 배경부터, null과의 차이점, 그리고 undefined를 현명하게 다루는 실전 테크닉까지. 이 글을 끝까지 읽고 나면, 더 이상 undefined를 두려워하는 대신 코드의 안정성을 높여주는 든든한 도구로 활용할 수 있게 될 것입니다.

1. 모든 것의 시작 undefined는 왜 만들어졌을까?

자바스크립트의 창시자 브렌던 아이크는 왜 undefined라는 개념을 만들었을까요? 이를 이해하려면 변수가 생성되는 과정을 상상해보면 쉽습니다. 우리가 코드로 let myVariable; 라고 선언하는 순간, 자바스크립트 엔진은 메모리에 myVariable을 위한 공간을 확보합니다.

그런데 여기서 질문이 생깁니다. “이 공간에 무엇을 채워 넣어야 할까?” 아직 개발자가 어떤 값을 할당할지 알려주지 않은 상태입니다. 이 “값이 아직 할당되지 않은 상태”를 표현하기 위한 약속이 필요했고, 그 결과로 탄생한 것이 바로 undefined입니다.

undefined를 비유하자면, ‘이름표는 붙어있지만 아직 아무것도 담지 않은 텅 빈 상자’ 와 같습니다. 상자(변수) 자체는 존재하지만, 그 내용물()은 비어있는 상태인 것이죠. 이처럼 undefined는 ‘오류’나 ‘잘못된 상태’가 아니라, ‘값이 아직 없음’을 나타내는 자바스크립트의 정상적인 상태 중 하나입니다.

2. undefined의 정체와 특징 파헤치기

undefined의 탄생 비화를 알았으니, 이제 그 구체적인 특징을 살펴보겠습니다.

undefined는 원시 값(Primitive Value)이다

자바스크립트에는 7개의 원시 자료형(String, Number, Boolean, Null, Undefined, Symbol, BigInt)이 있습니다. undefined는 이 중 하나로, 고유한 undefined 타입에 속하는 유일한 값입니다.

JavaScript

let a;
console.log(typeof a); // "undefined"

typeof 연산자를 사용해보면 undefined의 자료형이 문자열 “undefined”로 반환되는 것을 확인할 수 있습니다.

놀랍게도 undefined는 ‘변수’다?

한 가지 흥미로운 사실은 undefined가 자바스크립트의 키워드(예약어)가 아니라, 전역 객체(Global Object)의 속성 중 하나라는 점입니다. 즉, undefined는 변수처럼 취급됩니다.

JavaScript

// 브라우저 환경에서 window는 전역 객체입니다.
console.log(window.undefined); // undefined
console.log(window.hasOwnProperty('undefined')); // true

과거의 자바스크립트(ES5 이전)에서는 이 undefined 변수에 다른 값을 할당하는 황당한 일이 가능했습니다.

JavaScript

// 절대 따라하지 마세요!
var undefined = '이런 일이...';
let b;
console.log(b === undefined); // false! 코드가 엉망이 됩니다.

다행히 최신 자바스크립트 명세(ES5 이상)에서는 undefined 전역 변수를 읽기 전용(read-only)으로 만들어 재할당을 막았지만, 여전히 지역 스코프에서는 같은 이름의 변수를 선언할 수 있으므로 undefined라는 이름의 변수를 만드는 것은 반드시 피해야 합니다.

3. undefined는 언제 우리 앞에 나타날까? (대표적인 경우 4가지)

undefined는 다음과 같은 상황에서 주로 발생합니다.

1. 값을 할당하지 않고 선언만 한 변수

가장 대표적인 경우입니다. 변수를 선언했지만 어떤 값도 할당하지 않으면, 자바스크립트 엔진이 자동으로 undefined를 할당합니다.

JavaScript

let name;
console.log(name); // undefined

2. 객체에 존재하지 않는 프로퍼티에 접근할 때

객체에 없는 속성(프로퍼티)을 조회하려고 하면 undefined가 반환됩니다.

JavaScript

const person = {
  name: '홍길동',
  age: 30
};
console.log(person.job); // undefined (job 프로퍼티는 존재하지 않습니다)

3. 함수가 아무것도 명시적으로 반환하지 않을 때

함수에 return 문이 없거나, return 뒤에 아무 값도 명시하지 않으면 해당 함수는 undefined를 반환합니다.

JavaScript

function sayHello() {
  console.log('안녕하세요!');
  // return 문이 없음
}

const result = sayHello();
console.log(result); // undefined

4. 함수 매개변수가 전달되지 않았을 때

함수 호출 시 정의된 매개변수(parameter)의 개수보다 적은 인자(argument)를 전달하면, 전달받지 못한 매개변수는 undefined가 됩니다.

JavaScript

function printMessage(message) {
  console.log(message);
}

printMessage(); // undefined (message 매개변수에 아무것도 전달되지 않음)

4. undefined vs null: 영원한 논쟁의 종결

undefined와 자주 비교되는 개념이 바로 null입니다. 둘 다 ‘값이 없음’을 나타내지만, 그 속내와 쓰임새는 완전히 다릅니다. 이 둘의 차이점을 명확히 하는 것은 자바스크립트 실력의 중요한 척도입니다.

구분undefinednull
의미”값이 할당되지 않은 상태""의도적으로 비어있음을 명시한 상태”
자료형undefinedobject (언어 초기 설계의 유명한 실수)
발생 원인주로 자바스크립트 엔진에 의해 자동 할당주로 개발자가 코드에 직접 할당
사용 의도변수가 선언되었으나 아직 값이 없음해당 변수에 값이 없다는 것을 의도적으로 표현

‘빈 상자’ 비유를 다시 가져와 보겠습니다.

  • undefined: 이름표만 붙이고 아직 아무것도 담지 않은, ‘의도치 않은 빈 상자’

  • null: 내용물을 모두 비우고 ‘이 상자는 비어있음’이라고 써 붙여 놓은, ‘의도적인 빈 상자’

따라서 변수의 값이 없다는 것을 코드상에서 명확하게 표현하고 싶을 때는 undefined를 할당하는 것이 아니라, null을 할당하는 것이 올바른 컨벤션입니다.

JavaScript

// 좋지 않은 예
let user = undefined; 

// 좋은 예: 사용자가 없다는 것을 명시적으로 표현
let user = null; 

5. undefined를 다루는 실전 테크닉: 에러 없는 코드를 위하여

이제 undefined를 피하는 것이 아니라, 현명하게 다루는 방법을 알아볼 시간입니다. 안정적인 코드는 undefined가 발생할 수 있는 가능성을 항상 염두에 두고 작성해야 합니다.

1. 방어 코드의 기본, if 조건문

가장 기본적인 방법은 if 문을 사용하여 변수가 undefined인지 확인하는 것입니다.

JavaScript

function printUserName(user) {
  if (user !== undefined && user.name) {
    console.log(`사용자 이름: ${user.name}`);
  } else {
    console.log('사용자 정보가 없습니다.');
  }
}

printUserName({ name: '김코딩' }); // 사용자 이름: 김코딩
printUserName(); // 사용자 정보가 없습니다.

2. 기본값 할당의 달인, 논리 연산자 활용

undefined일 경우 기본값을 설정해주고 싶을 때 논리 연산자(OR ||, Nullish Coalescing ??)를 유용하게 사용할 수 있습니다.

a) OR 연산자 (||)

|| 연산자는 왼쪽 값이 ‘falsy’한 값(false, 0, "", null, undefined, NaN)일 경우 오른쪽 값을 반환합니다.

JavaScript

function welcome(name) {
  const userName = name || '손님';
  console.log(`안녕하세요, ${userName}님!`);
}

welcome('이개발'); // 안녕하세요, 이개발님!
welcome(); // 안녕하세요, 손님님!

주의! || 연산자는 0이나 빈 문자열 ''처럼 유효한 값일 수 있는 falsy 값도 걸러내기 때문에 의도치 않은 결과를 낳을 수 있습니다.

b) 널 병합 연산자 (??, Nullish Coalescing Operator)

이러한 || 연산자의 단점을 보완하기 위해 등장한 것이 널 병합 연산자 ??입니다. ??는 왼쪽 값이 undefined 또는 null일 경우에만 오른쪽 값을 반환합니다.

JavaScript

let itemCount = 0;

// || 연산자의 경우, 0이 falsy이므로 1이 할당됨
const count1 = itemCount || 1; 
console.log(count1); // 1 (의도와 다름)

// ?? 연산자의 경우, 0은 undefined나 null이 아니므로 0이 할당됨
const count2 = itemCount ?? 1;
console.log(count2); // 0 (의도대로 동작)

따라서 기본값을 설정할 때는 || 보다 ??를 사용하는 것이 더 안전하고 명확합니다.

3. 에러 방지의 끝판왕, 옵셔널 체이닝 (?.)

TypeError: Cannot read properties of undefined 에러는 대부분 undefined인 값의 프로퍼티에 접근하려 할 때 발생합니다.

JavaScript

const user = null;
// console.log(user.address.street); // TypeError 발생!

이런 상황을 방지하기 위해 과거에는 if문을 중첩해서 사용했습니다.

JavaScript

if (user && user.address) {
  console.log(user.address.street);
}

**옵셔널 체이닝 ?.**은 이 과정을 획기적으로 줄여줍니다. ?. 앞의 평가 대상이 undefinednull이면 에러를 발생시키지 않고 undefined를 반환합니다.

JavaScript

const user1 = {
  name: '박해커',
  address: {
    city: '서울'
  }
};
const user2 = null;

console.log(user1?.address?.street); // undefined (에러 없음)
console.log(user2?.address?.street); // undefined (에러 없음)

옵셔널 체이닝과 널 병합 연산자를 함께 사용하면 매우 안전하고 간결한 코드를 작성할 수 있습니다.

JavaScript

const street = user1?.address?.street ?? '주소 정보 없음';
console.log(street); // 주소 정보 없음

결론: undefined와 친구 되기

지금까지 우리는 undefined의 탄생 배경부터 실전 활용법까지 깊이 있게 탐험했습니다. undefined는 더 이상 피해야 할 대상이나 에러의 원흉이 아닙니다. 오히려 우리에게 ‘이 변수는 아직 준비되지 않았어’라고 알려주는 친절한 신호입니다.

undefined가 발생하는 경우를 이해하고, if문, ??, ?.와 같은 도구들을 적재적소에 활용하여 방어적으로 코딩하는 습관을 들인다면, 코드의 안정성은 비약적으로 향상될 것입니다. 이제 undefined를 두려워하지 말고, 여러분의 코드를 더욱 견고하게 만들어주는 든든한 친구로 만들어보세요. 에러 없는 코딩의 시작은 바로 이 작은 개념을 완벽히 이해하는 것에서부터 출발합니다.