2-4 특수 값

Nomade_Simia·2021년 11월 24일
0

📌이번에는 특수 값에 대해 알아보자


.
.
.

📎값 아닌 값


.
.
.

undefined, Null 타입의 값은 각각 undefined Null밖에 없다. 그래서 이 둘은 타입과 값이 항상 같다.

undefinedNull은 종종 '빈(empty)' 값과, '값아닌(nonvalue)'값을 나타낸다.

다른의미로는

  • null은 빈값,undefined는 실종된 값
  • null은 예전에 값이 있었지만 지금은 없는 상태, undefined는 값을 아직 가지지 않은 상태

두 타입에 어떤 의미를 정의 하던지 null은 식별자가 아닌 특별한 키워드 이므로 null이라는 변수에 뭔가 할당 할 수는 없다.

하지만...... 불행하게도 undefined는 식별자로 사용할 수 있다.
.
.
.

📎특수 숫자

숫자 타입 안에는 몇가지 특수한 값이 있다.


.
.

1️⃣ The not number, number

수학 연산시 두 피연산자가 전부 숫자가 아닐 경우 유효한 숫자가 나올수 없으므로 결과는 NaN(not a number)이다.

그런데 이 명칭은 오해의 소지가 있다. NaN'숫자 아님'이 아닌 '유효하지 않은 숫자' 혹은 '실패한 숫자'라고 하는 편이 정확하다.

💻 code

var a = 2 / 'foo' // NaN

typeof a === "number" // true

즉 '숫자 아님의 타입은 숫자이다!'🙄

💡NaN은 경계값의 일종으로 숫자 집합 내에서 특별한 종류의 에러 상황을 나타낸다.

그럼 여기서 우리는 NaN여부를 식별하고 싶을 때가 있을 것이다. 그럴때 우리는 null, undefined처럼 비교하고 싶겠지만 땡(❌)이다!

💻 code

var a = 2 / 'foo';

a == NaN; // false;
a === NaN; // false;

NaN은 어떤 NaN과도 동등하지 않다. 그렇다면 NaN값은 어떻게 확인 할까?

💻 code

var a = 2 / 'foo';
isNaN(a); // true

우리는 내장 유틸리티 함수 isNaN()을 사용하면 된다!
그렇다고 isNaN()이 무적인가? 아니다!💢

isNaN()에는 치명적인 결함이 있다. 이 함수는 NaN을 글자 그대로 해석해서 인자값이 숫자인지 아닌지 판단하는 기능이 전부이다.

💻 code

var a = 2 / 'foo';
var b = 'foo';

a; // NaN
b; // 'foo'

window.isNaN(a); // true
window.isNaN(b); // true 😥?????

foo는 숫자가 아니지만 그렇다고 NaN도 아니다. 이 버그는 자바스크립트 탄생이후 무려 19년 동안 계속되었다.

하지만 드디어 ES6부터 Number.isNaN()으로 해결 되었다.

2️⃣ 무한대(Infinity)

.
.

JS는 0으로 나누기 연산이 잘 정의 되어있어 에러 없이 Infinity라는 결과 값이 나온다.

💻 code

var a = 1 / 0 ; //Infinity
var b = -1 / 0 ; // -Infinity

.
.

3️⃣ Zero(0)

우리가 수학을 배웠다면 음의 정수와 양의 정수 사이에 0이 있다는 것을 알 수 있다.

하지만! 우리의 JS는 기대를 져버리지 않고 0에 부호가 있다!🤯🤯🤯

💻 code

var a = 0 / -3; // -0
var b = 0 * -3; // -0

그러나 명세에 의하면 -0을 문자열화 하면 항상 "0"이다.

💻 code

var a = 0 / -3;

//(일부 브라우저에서만 제대로 표기한다.)

a; // -0

// 하지만 명세는 우리에게 구라를 친다!?

a.toString(); // "0"
a + ""; // "0"
String(a); // "0"

//이상하게 JSON도 속는다. (바본가..)
JSON.stringify(a); // "0"

신기하게도 반대로 하면 정상 작동한다.(진짜 뭐지)

💻 code

+"-0" // -0
Number("-0"); // -0
JSON.parse("-0"); // "-0"

👽 JSON.parse("-0")는 -0인데 JSON.stringify(a)는 "0"이다. 우리의 JS는 알다가도 모르겠다..

심지어 -0은 비교 연산자도 속인다.

💻 code

var a = 0;
var b = 0 /-3;

a == b; //true
-0 == 0; // true

a === b; // true
-0 === 0; // true

0 > -0; // false
a > b; // false

그렇다면 0에 부호는 왜 존재할까?
값의 크기로 어떤 정보와 그 값의 부호로 또다른 정보를 동시에 나타내야 하는 애플리케이션이 있기 때문이다.(ex 애니메이션 프레임당 넘김 속도와 넘김 방향)
.
.
.

📎특이한 동등 비교


앞서 보았듯 NaN-0의 동등 비교는 독특하다.
NaN은 자기 자신과도 동일하지 않아 Number.isNaN()또는 폴리필을 사용해야하고
-0도 구라쟁이라서 isNegZero() 같은 함수를 사용해야한다.

ES6부터는 잡다한 예외를 걱정하지 않아도 두 값이 절대적으로 동등한지를 확인하는 새로운 유틸리티를 지원한다. 바로 Object.is()이다.

💻 code

var a = 2/ 'foo';
var b = -3 * 0;

Object.is(a, NaN); // true
Object.is(b, -0); // true
Object.is(b, 0); // false

== ===가 안전하다면 굳이 사용할 필요 없다.
기본연산자가 좀더 효율이 좋고 일반적이기 때문이다.

.
.
.

🚪 마치며


오늘은 특수 값에 대해 알아보았다. 특수 값은 JS를 사용하면서 별로 사용해보지 못했던 것 같다.

이걸 이용하면 신기한 코드를 만들어 볼 수도?... (버그걸리려나?)
.
.
.

profile
코딩 잘하고 싶은 코딩몽키

0개의 댓글