본 글은 정재남님의 저서 <코어 자바스크립트>를 읽고 정리한 내용입니다.
자바스크립트에는 '없음'
을 나타내는 값이 두 가지
있다.
두 값의 의미는 비슷하지만 미세하게 다르고, 사용하는 목적 또한 다르다.
undefined는 사용자가 명시적으로 지정할 수도 있고, 값이 존재하지 않을 때 자바스크립트 엔진이 자동으로 부여하는 경우가 있다.
자바스크립트 엔진은 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제로는 그렇게 하지 않았을 때 undefined를 반환한다. 아래 세 경우가 이에 해당한다.
var a;
console.log(a); // undefined, (1)의 경우
var obj = { a: 1 };
console.log(obj.b); // undefined, (2)의 경우
var func = function(){};
console.log(func()); // undefined, (3)의 경우
배열
의 경우 조금 특이한 동작을 확인할 수 있다.
var arr1 = [];
arr1.length = 3;
console.log(arr1); // [empty * 3]
var arr2 = new Array(3);
console.log(arr2); // [empty * 3]
var arr3 = [undefined, undefined, undefined];
console.log(arr3) // [undefined, undefined, undefined]
위 코드 예에서 보면 arr1
과 arr2
는 [empty *3]
이 출력되었다. 배열에 3개의 빈요소를 확보했지만 각 요소에는 문자 그대로 어떤 값도, 심지어 undefined도 할당돼 있지 않음을 의미한다.
이와 반대로 arr3
의 경우 undefined
가 값
으로써 할당
된 크기가 3인 배열이 출력되었다.
이처럼 '비어있는 요소'
와 'undefined'
를 할당
한 요소
는 출력 결과부터 다르다.
'비어있는 요소'는 순회와 관련된 많은 배열 메서드들의 순회 대상에서 제외된다.
var arr1 = [undefined, 1]; // [ undefined, 1 ]
var arr2 = [];
arr2[1] = 1; // [ <1 empty item>, 1 ]
arr1.forEach(function (v, i) { console.log(v, i) }); // undefined 0 / 1 1
arr2.forEach(function (v, i) { console.log(v, i) }); // 1 1
arr1.map(function (v, i) { return v + i }); // [ NaN, 2 ]
arr2.map(function (v, i) { return v + i }); // [ <1 empty item>, 2 ]
위 코드 예제를 보면,
사용자가 직접 undefined
를 할당
한 arr1
에 대해서는 일반적으로 알고 있는 대로 배열의 모든 요소를 순회해서 결과를 출력한다. 하지만 arr2
에 대한 결과를 보면 각 메서드들이 비어있는 요소에 대해서는 어떠한 처리도 하지 않고 건너뛰었음을 알 수 있다.
따라서 사용자가 명시적으로 부여한 경우와 비어있는 요소에 접근하려 할 때 반환되는 두 경우의 'undefined'
의 의미를 아래와 같이 구분할 수 있겠다.
전자
의 undefined는 그 자체로 값
이다. undefined가 비어있음을 뜻하긴 하지만 여기서는 하나의 값으로 동작하기 때문에 해당 배열의 요소는 고유의 키값이 실존하게 되고, 따라서 순회의 대상이 될 수 있다.
후자
의 경우 배열의 키값 (인덱스) 자체가 존재하지 않고 문자 그대로 값이 없음을 나타낼 뿐이다.
위에서 undefined 가 두 가지 동작을 하는 것을 알아보았다. 그럼 동작 방식이 다른 undefined를 어떻게 사용해야 할까?
답은 둘 중 하나만 사용하는 것이다.
자바스크립트 엔진이 반환하는 undefined
의 경우 우리의 통제 범위를 벗어나므로 모든 undefined는 오직 이 경우에만 해당하게끔 하는 것이다.
다시 말해, 직접 undefined를 할당하지 않으면 되는 것이다.
비어있다는 의미를 명시적으로 나타내고 싶을 때는 'null'
을 사용하도록 하자. null
은 애초에 이러한 용도로 만들어진 데이터 타입이다.
null을 사용할 때 한 가지 주의점이 있다.
바로 typeof null
이 object
라는 점이다. 이는 자바스크립트 버그라고 한다. 따라서, 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
n === null
를 활용하도록 하자