728x90

본 강의는 자바스크립트의 기초를 대충 안다고 가정하고 시작하는 조금 심도 깊은 포스팅이다.

완전 처음부터 배우고 싶다면 다른 블로그나 책의 글을 참조하기를 바란다.

특별한 추가 설명이 없다면 nodejs가 아닌 브라우저에서 사용하는 js를 의미한다.


참고:

javascript docs

ecmascript specification


보통 언어들에서는 값이 없다.

값이 들어있지 않다라는 상태를 나타내는 변수는 null이다.

c++의 경우 nullptr, python의 경우 None을 사용하긴 하는데 뭐 어쨋든 다 null이라는 뜻이다.


null상태를 c++의 경우 2가지의 방식으로 제공하는데 NULL과 nullptr이다.

하지만 NULL은 사실 매크로로 0이 래핑된거고 실제 null은 nullptr이며 사실상 둘은 진짜 아아아아아아주 예이적인 경우를 제외하곤

혼용해서 써도 문제없을만큼 완벽하게 동작한다. 실제로 프로그래머가 둘을 혼용해서 일어나는 문제는 사실 상 없다.


하지만 js의 undefiend와 null, NaN이 존재하며 심지어 이게 ==,===,false와 같이 적용될 경우 심각한 문제를 야기한다.

그래서 이번에는 각각에 대해서 알아보도록 하자.


값이 없다, 초기화한적 없다 => undefined


js에서는 undefiend라는 키워드가 제공된다.

이 녀석도 다른 언어에서는 보통 없는데 쉽게 말하면 초기화된적 없는 상태를 나타내는 프리미티브 타입,

즉 기본 타입을 의미한다.


필자가 느끼는 바에 의하면 정말 유용하고 좋은 타입이다.

null만 사용하면 초기화가 됬다 없어진건지도 모르지만

그것보다 더 좋은건 js문법과 맞물려서 일어나는 헤프닝 들이다.


var arr = [];
console.log(arr[0]);

이러한 코드는 js에선 잘 동작한다.

동작 원리를 설명해 줄려면 시간은 걸리지만 쉽게 이야기하면 동작한다는 것이다.

이 때 우리는 0번째 원소를 선언한적이 없으므로 당연히 값이 초기화된적이 없다.

이 경우 undefiend가 반환된다.


var val;
console.log(typeof val);

undefiend는 기본 스펙을 보면 알겠지만 하나의 기본 자료형으로서 typeof를 실행하면 undefiend가 실행된다.

이 까지보면 아주 좋은 상태 변수이다.

그리고 이러한 변수가 null과 조합되면 더 유용하게 쓰일 수 있지 않을까?

그런 생각은 당연히 프로그래머들의 머릿속에도 맴돌고 있었지만 그 이야기는 나중에 하도록하자.


하지만 이 undefiend는 생각보다 지랄 맞은 점이 많다.

가령 아래와 같은 코드를 보자.

console.log(undefined || true); //true
console.log(undefined || false); //false

undefiend는 일반적으로 부울린 값으로 사용할 경우 false로 취급한다.

이는 초기화를 판단하는 undefiend와 boolean의 콜라보레이션으로 아래와같은 테크닉이 가능하다.


var val;
val = val || 10;

위와 같은 코드의 경우 val이 만약 초기화가 되지 않았다면 10을 부여한다.

사실 이 문법을 더 자세히 이해하려면 js가 and, or을 어떤 메커니즘으로 처리하는지 알아야한다.


var val;
console.log(new Number(val));

만약 undefiend을 숫자로 번역하게 된다면 값은 NaN이된다.

NaN이 뭔지는 추후에 알려드리겠다.


없는 값이다 => null

null은 다른언어에도 있으니 설명이 길게 필요하진 않은것 같다.


if(null){
console.log('true')
}else{
console.log('false')
}
//false

null역시 부울린 사용시 false로 반환된다.

따라서 이러한 코드도 가능하다.


if(null == undefined){
console.log('true')
}else{
console.log('false')
}
//true

if(null === undefined){
console.log('true')
}else{
console.log('false')
}
//false

undefined와 null은 둘다 false로 취급 되므로 둘이 비교하면 false가 된다.

그러나 동등연산자는 서로 같은 객체인지 비교하므로 둘은 다르게 해석된다.

null은 개같은 특성이 하나있는데 이는 아래와 같다.


console.log(typeof undefined) //print undefined
console.log(typeof null) //print object

typeof 연산자는 그 객체의 개략적인 타입을 알 수 있다.

프리미티브타입은 undefined와 null의 경우 서로 프리미티브타입을 출력할 것 같지만 실제로는 그렇지않다.

null의 경우 특이하게 object를 출력하게 된다.

그래서 null이 object라고 아는 사람들도 있던데 당연히 null은 null이다.

null이 object로 출력하게된 이유는 과거부터 내려오는 유서깊은 코드를 바꾸길 미뤘다가 일어난 참사이다.

거기에 대한 설명은 이 사이트에서 확인하면된다.


어쨋든 null인지 확인하는 방법은 typeof를 사용해서는 안된다. 물론 그런 코드를 쓸일은 거의 없다.


console.log(new Number(null))//0

그리고 null을 숫자로 변환하면 0이된다.


console.log(new Number(null)==new Number(undefined))//false

그래서 둘이 그냥 비교했을 때는 같다고 반환했던 놈이 new Number를 감싸면 서로 다르게 뱉는다.

이게 은근 코드를 꼬이게 만드는 경우가 있기 때문에 조심해야 한다.


이 값은 숫자가 아니다 => NaN

var val;
val = Number(undefined);
console.log(val);//NaN

NaN는 js에서만 있는 특별한 값이다.

숫자가 아니라는 뜻이다.

숫자가 들어가야할때 다른 값들이 들어간다면 만약 치환이 안된다면 위 처럼 NaN이된다.

그래서 또 신비한 삼각관계가 형성되는데 바로 아래같은 상황이 된다.


var val;
val = Number(null);
console.log(val);//0

이렇게 비교하게 되면 또 0이나오게된다.

물론 NaN 역시 부울린으로 사용하면 false로 반환된다.


if(NaN){
console.log('true')
}else{
console.log('false')
}//false

이렇게 false로 나오지만 또 아래같은 비교는 이상한 값이 나온다.


console.log(NaN==undefined);//false
console.log(NaN==null);//false
console.log(undefined==null);//true

NaN은 값으로 서로 비교를 행하게 될경우 신기하게도 null과 undefined와 할 경우 false가 된다.

그래서 NaN생성의 가능성이 있다면 비교연산을 행해서는 안된다.

그리고 당연히 동등연산은 더더욱 실행하면 안된다.


하지만 NaN은 훨씬 골때리는 일이 남아있다.


console.log(NaN===NaN);//false
console.log(NaN!==NaN);//true

자기를 동등연산을 하면 false가 나오는 미친 값이다.

그래서 이를 동등비교로 써먹는건 불가능 하고 전용함수를 써야하는 귀족 녀석이다.


console.log(isNaN(NaN));//true

NaN은 isNaN을 써야만 확인할 수 있다.


console.log(typeof NaN);//number

그리고 type은 당연히 숫자이다.

숫자가 아닌 값이 숫자라는게 철지난 아재개그 같은 느낌이다.


console.log(isNaN('str'));//true

그리고 isNaN함수에 문자열을 넣어도 성립한다.....

사실 문자열이 아니라 object를 넣어도 성립하게된다.

정말 이상한놈이라서 취급에 주의 해야한다.


결론

1.typeof 사용시 undefined는 undefined, null은 object, NaN은 number가 반환된다.

2.NaN==undefined는 false다.

3.NaN==null은 false다.

4.null==undefined는 true다.

5.NaN과 null과 undefined는 일반적으로 비교할땐 false로 취급한다.

6.null은 숫자의 경우 0이 된다.

7.undefined는 숫자의 경우 NaN이 된다.

6.NaN의 비교는 isNaN으로 하지 않는다면 결과를 예측할 수 없다.


+ Recent posts