동명의 해체된 오버워치 프로게임단에 대한 내용은 UNDEFINED(프로게임단) 문서
, Xdinary Heroes의 노래에 대한 내용은
UNDEFINED(Xdinary Heroes)
문서
참고하십시오.관련 문서: 컴퓨터/표현
프로그래밍 언어 문법 | ||
{{{#!wiki style="margin: -16px -11px; word-break: keep-all" | <colbgcolor=#0095c7><colcolor=#fff,#000> 언어 문법 | C( 포인터 · 구조체) · C++( 자료형 · 클래스 · 이름공간 · 상수 표현식 · 특성) · C# · Java · Python · Kotlin · MATLAB · SQL · PHP · JavaScript · Haskell |
마크업 문법 | HTML · CSS | |
개념과 용어 | 함수 · 인라인 함수 · 고차 함수 · 람다식 · 리터럴 · size_t · 상속 · 예외 · 조건문 · 참조에 의한 호출 · eval | |
기타 | == · === · deprecated · NaN · null · undefined · 모나드 · 배커스-나우르 표기법 | |
프로그래밍 언어 예제 · 목록 · 분류 | }}} |
1. 개요
undefined는 JavaScript 언어에서 '아직 할당하지 않은 값'을 표현하기 위해 사용하는 값이다. null과는 사용 방식이 약간 다른데, null이 아예 '일부러 비워 둔 값'을 의미하는 것이라면, undefined는 아직 변수 또는 프로퍼티가 할당되지 않았음을 의미한다. 비슷해 보이는 용어인 'undefined behavior'와는 다른 개념이다.[1]2. 발생하는 경우
자바스크립트에서는 정말 자주 볼 수 있는데, 객체에서 없는 프로퍼티를 꺼내려고 하거나[*#!syntax javascript
const obj = {};
obj.a // undefined
], 함수를 호출할 때, 값이 들어오지 않은 매개변수를 사용하려 한다거나[* #!syntax javascript
function f(a, b) {
console.log(a);
console.log(b);
}
f(1) // a는 1이 나오지만, b는 undefined로 출력됨
], 아직 값이 할당되지 않은 변수를 사용하려 할 때[* #!syntax javascript
let a;
a // undefined
][2], 배열의 범위를 넘어서는 값을 가져오려 할 때[* #!syntax javascript
[1, 2, 3][3] // undefined
][3], 그리고 함수가 아무것도 반환하지 않을 때[* #!syntax javascript
function a () {}
a() // undefined
]도 undefined
를 만날 수 있다! 이런 특징으로 인해 디버깅이 상당히 어려워지는데,
undefined
는 (객체가 아니기에) 속성도 가지지 않고, (함수도 아니기에) 호출할 수도 없다. 그래서 코드 중간에서 오타 등으로 인해 존재하지 않는 프로퍼티를 꺼냈을 때, 원하는 값 대신 undefined
가 나오게 되고, 이 값을 나중에 사용하는 부분에서 Uncaught TypeError: Cannot read property '...' of undefined
또는 Uncaught TypeError: ... is not a function
등의 오류를 맞닥트리게 되며, 버그의 원인과 발견 지점이 멀어지게 되고, 결국엔 디버깅 난이도를 높이게 된다. 즉, Java같은 상식대로면 진작에 값이 없는 것을 참조하므로 NullPointer Exception이 발생해서 멈췄을 부분에서 조용히 지나가버리게 되기 때문이다.자바스크립트 뿐만 아니라, 몇몇 GCC에서는 선언만 된 배열의 주소를 반환하는 것이 경고만 뜨고 허용되는 경우가 있다고 한다.
3. 왜 있는가?
위의 문제점에서 보다시피 undefined는 디버깅에 혼선을 주는데다 아무 쓸모도 없어서 대체 왜 있는가 싶지만, 이것의 진정한 의의는 오버헤드를 줄여 런타임을 최적화 하는데 있다.참조할 변수에 할당이 이뤄졌는지를 먼저 체크하면 이런 식의 런타임 에러는 막을 수 있겠지만 그만큼 시간이 더 걸리기 때문에, 성능을 확보한 대신 이러한 상황을 개발자에게 막도록 한 것이다. 특히 undefined를 자주(...) 볼 수 있는 자바스크립트는 대체로 웹브라우저에서의 동작을 상정하는데, 웹브라우저의 처리 성능은 Native로 돌리는 것에 비해 대개 처참한 수준이므로 이런식으로라도 최적화가 이뤄져야한다. 생략한 설명이 많지만 이 문제는 꽤 예전(92년도!)에 다뤄졌던 '컴파일러가 C 표준을 무시하지 않고 임의대로 처리해도 되는가'라는 'Nazal Demon 문제(악마가 코로 들어갈 수 있어도 되는가)에 관한 토론'에서 잘 다루고 있다.[5] 토론 당시에 비해 하드웨어 성능도 월등해지고 소프트웨어도 규격/정밀화된 지금은 거의 '언어 컨셉'에 따라 undefined behavior를 허용하는 것으로 굳어졌다.
4. 하스켈에서
하스켈에서undefined
는 프로그래머가 이름과 타입만 정하고 아직 값을 정하지 않은 것에 부여할 수 있는 값이다.[6] 하스켈의 소극적인 실행(lazy evaluation) 덕분에 거의 아무 곳에나 undefined
를 적어도 컴파일 에러가 나지 않는다.
[1]
JavaScript에서 'undefined behavior'에 의해 'undefined'가 주로 발생하기는 한다.
[2]
참고로 아예 선언 자체를 안한 변수를 사용하려고 하면
Uncaught ReferenceError: ... is not defined
예외가 발생한다.
[3]
다만 이 경우는 1번 경우의 특수한 사례인데, 자바스크립트에서 배열은 객체의 일종이기 때문이다. 즉 arr라는 배열이 있을 때, arr[0]
는 arr객체의 0이라는 프로퍼티를 꺼낸 것과 같다.
[4]
[][[]]+[][[]]
만으로 NaN이 나온다!
[5]
https://groups.google.com/g/comp.std.c/c/ycpVKxTZkgw/m/S2hHdTbv4d8J?hl=en
[6]
https://wiki.haskell.org/Undefined