본문으로 건너뛰기
yceffort
PostsSeriesTagsAbout🧪 Research
EN

Tweaks

theme
accent palette
film grain
minimal mode
BACK TO INDEX
◆ ESSAY
--min
--year
KOoriginal

mailMail icongithubtwitter
yceffort
•
© 2026
•
https://yceffort.kr
BACK TO INDEX
◆ ESSAY

null과 undefined의 차이, 그리고 역사

avatar
yceffort
2021-02-02 · 4분
4min
2021year
KOoriginal
javascript

ECMAScript 언어 명세 상의 차이

  • undefined: 변수에 값이 할당되지 않았을 때 사용된다. https://tc39.es/ecma262/#sec-undefined-value primitive value used when a variable has not been assigned a value

  • null: 의도적으로 어떤 객체의 값이 비어 있다는 것을 나타낼 때 사용된다. primitive value used when a variable has not been assigned a value primitive value that represents the intentional absence of any object value

다른 언어와 다르게, 두개의 non-value가 있는 것은 자바스크립트 설계의 실수라고 한다. 그러나 이것이 지금까지 사용되고 있는 것은 자바스크립트가 구버전과의 호환성을 절대로 깨뜨리지 않는 다는 원칙이 있기 때문이다. 비슷한 사례로 typeof null이 있다.

자바스크립트가 많은 영감을 받은 자바에서는, 변수의 정적 타입에 따라 값을 초기화 한다.

  • 객체 타입의 변수는 null로 초기화 한다.
  • 원시 타입의 변수는 각자의 초기 값으로 초기화 한다. 숫자의 경우 0 이다.

자바스크립트의 경우에는, 변수가 객체가 될 수도 있고, 원시값이 될 수도 있다. 그러므로 만약 null이 "객체가 아니다" 라면, 자바스크립트는 "객체도 아니고 원시값도 아닌" 초기 값이 필요해 진다. 그것이 바로 undefined 다.

undefined가 나오는 경우

// 초기 값을 주지 않은 경우
let var

// 객체에서 정의 하지 않은 속성에 접근하는 경우
const obj = {}
obj.prop

// 함수의 리턴이 없는 경우
function func() {}
assert.equal(func(), undefined)

// 리턴은 있는데 아무것도 안하는 경우
function func() {
  return
}
assert.equal(func(), undefined)

function func(x) {
  assert.equal(x, undefined)
}

// 정의 되지 않은 파라미터
func()

undefined?.prop
null?.prop

null이 나오는 경우

// 프로토타입의 종점
Object.getPrototypeOf(Object.prototype) // null

// 정규식
/a/.exec('x') // null

// JSON은 undefined를 지원 하지 않는다.
JSON.stringify({a: undefined, b: null}) // "{"b":null}"

undefined와 null을 특별하게 처리하는 연산자

함수 파라미터의 기본값

함수 파라미터의 기본값은 두가지 경우에서만 사용된다.

  • 파라미터가 존재하지 않는 경우
  • 파라미터의 값이 undefined인 경우
function func(arg = 'abc') {
  return arg
}
console.log(func()) // abc
console.log(func(undefined)) // abc
console.log(func(null)) // null

분해연산자의 기본값과 undefined

위의 기본값 예제와 동일하게 동작한다.

const [a = 'a'] = [] // a
const [b = 'b'] = [undefined] // b
const {prop: c = 'c'} = {} // c
const {prop: d = 'd'} = {prop: undefined} //d
const [e = 'e'] = [null] // null
const {prop: f = 'f'} = {prop: null} // null

옵셔널 체이닝

값이 nullish한 경우 (null undefined) undefined를 리턴한다.

function getProp(obj) {
  return obj?.prop
}
getProp({prop: 123}) // 123
getProp(undefined) // undefined
getProp(null) // undefined

undefined, null, nullish coalescing (null 병합 연산자)

|| 와는 다르게 nullish 한 값에 대해서만 대응한다.

undefined ?? 'default value' // default value
null ?? 'default value' // default value
0 ?? 'default value' // 0
'' ?? 'default value' // ''

null 병합 할당 현산자인 ??= 도 마찬가지로 동작한다.

결론(?)

명시적으로 값이 없다는 걸 나타내고 싶다면, null을 쓰는게 좋다. undefined는 기본값 할당, JSON에서 생략되는 등 의도치 않은 동작을 나타낼 수 있다. 내가 의도적으로 빈값을 두고 싶다면, null이 나은 것 같다. 그렇다고 undefined가 내가 짠 코드에서 안나오는 것은 아닐 것이다. 말하고 싶은 것은 의도적으로 빈값을 집어 넣을 때 둘중에 null을 더 선호한다 정도일 것이다. 그러나 이건 어디까지나 내취향의 문제일 뿐, 적절히 헷갈리지만 않게 쓰면 될 것 같다.

관련 글

  • #turbopack#nextjs#bundler

    Next.js turbopack에서 싱글톤이 두 개가 됐다: scope hoisting 버그와 순환 import

    Next.js 16 turbopack 프로덕션 빌드에서 모듈 스코프 싱글톤이 런타임에 두 개가 됐다. 같은 동기 구간에서 조건 판정이 뒤집히고, 응답이 도착해도 타임아웃이 나는 증상을 번들 산출물로 추적한 기록. scope hoisting의 부분 병합, 순환 import, 이미 고쳐져 있던 upstream 버그, 그리고 뒤늦게 돌린 단일 변수 실험까지.

    2026-08-19·28분
  • #javascript#animation#web-animations-api

    number-flow를 구형 브라우저로 이식하기: 다섯 가지 결정과 두 가지 번복

    number-flow가 애니메이션을 켜는 최소 버전은 Chrome 125, Safari 17.2다. 이 하한을 Chrome 66과 WebKit 16.4까지 내리는 포크를 만들면서 내린 결정들과, 뒤집게 된 판단 두 가지, 그리고 자동 강등을 포기한 Safari 버그 조사의 기록.

    2026-08-11·44분
  • #nodejs#security#javascript

    Node.js vm 모듈의 함정: 샌드박스가 아닌 이유

    집필 중인 Node.js Deep Dive의 5.2장(vm 모듈의 함정) 일부를 미리 공개합니다.

    2026-02-27·25분
  • #nodejs#javascript

    Node.js Deep Dive (가제) 베타 리더를 모십니다.

    많관부22

    2026-02-19·5분

새 글을 놓치고 싶지 않으시다면 RSS로 구독해 주세요.

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다. 발표·기술 자문·기고 문의는 이곳에서 받고 있습니다.

← Back to the blogIssue on GitHub →