undefined
가 나오는 상황은 크게 2가지가 있습니다.
undefined
를 지정할 경우var arr1 = [undefined, 1];
arr1.forEach(function (v) { console.log(v); }); // undefined / 1
undefined
는 그 자체로 하나의 값(실존하는 데이터)이기도 하기에 직접 지정할 경우 순회의 대상이 됩니다.
var arr2 = [];
arr2[1] = 1;
arr2[0] // undefined
arr2.forEach(function (v) { console.log(v); }); // 1
값을 직접 지정하지 않고 빈 공간(empty)로 남겨둘 경우, 이에 접근하려고 한다면 undefined
를 출력하고 순회의 대상이 되지 않습니다. 이때의 undefined
는 문자 그대로 비어있음을 나타냅니다.
arr1.map(function (v, i) { return v + i; }); // [NaN, 2]
arr2.map(function (v, i) { return v + i; }); // [empty, 2]
arr1.filter(function (v, i) { return !v; }); // [undefined]
arr2.filter(function (v, i) { return !v; }); // []
arr1.reduce(function (p, c, i) { return p + c + i; }); // undefined011
arr2.reduce(function (p, c, i) { return p + c + i; }); // 11
위 코드를 확인해보면 값을 할당하지 않은 arr2[0]
에 대해서는 배열 메소드가 동작하지 않는 모습을 볼 수 있습니다. 즉, 값이 지정되지 않은 인덱스는 아직 존재하지 않는 프로퍼티에 지나지 않습니다.
배열은 무조건 length 프로퍼티의 개수만큼 빈 공간을 확보하고 각 공간에 index를 이름으로 지정하는 것이 아닌, index 값을 지정할 때 비로소 빈 공간을 확보하고 index를 이름으로 지정하여 데이터의 주솟값을 저장하는 등의 동작을 수행합니다.
어떤 undefined
는 순회의 대상이 되고 또 다른 undefined
는 순회의 대상이 되지 않습니다. 이런 혼란을 피하기 위해서 둘 중에 하나만 사용하는게 좋을 것 같지만 Javascript Engine이 undefined
를 반환하는 경우는 우리의 통제를 벗어나기 때문에 우리가 직접 undefined
할당하지 않기만 하면 됩니다.
그럼 어떻게 비어있음을 표현할까요?
비어있음을 표현하기 위해 만들어진 데이터 타입인 null
을 이용하면 됩니다.
다만 typeof null
이 object
라는 Javascript 자체 버그가 존재하기 때문에
어떤 변수의 값이 null
인지 판별하기 위해선 typeof
대신 일치 연산자(===)를 사용해야 합니다.
var n = null;
console.log(typeof n); // object
console.log(n == undefined); // true
console.log(n == null); // true
console.log(n === undefined); // false
console.log(n === null); // true